Import multibus branch as trunk.
This commit is contained in:
commit
cd25d4af06
42 changed files with 1998 additions and 1389 deletions
|
@ -2,7 +2,7 @@ PROJECT(libnfc C)
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
SET(VERSION_MAJOR "1")
|
||||
SET(VERSION_MINOR "2")
|
||||
SET(VERSION_PATCH "1+svn")
|
||||
SET(VERSION_PATCH "1")
|
||||
|
||||
SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
|
||||
|
||||
|
|
41
configure.ac
41
configure.ac
|
@ -1,11 +1,13 @@
|
|||
# SVN revison
|
||||
define([svn_revision], esyscmd([sh -c "svnversion -n"]))
|
||||
SVN_REVISION=svn_revision
|
||||
|
||||
# General init
|
||||
AC_INIT(libnfc, 1.2.1, info@libnfc.org)
|
||||
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
# SVN revison
|
||||
define([svn_revision], esyscmd([sh -c "svnversion -n"]))
|
||||
SVN_REVISION=svn_revision
|
||||
AC_DEFINE_UNQUOTED([SVN_REVISION], ["$SVN_REVISION"], [SVN revision])
|
||||
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
AC_LANG_C
|
||||
|
@ -21,8 +23,6 @@ case "$host" in
|
|||
;;
|
||||
esac
|
||||
|
||||
AC_PROG_RANLIB
|
||||
|
||||
AC_PATH_PROG(PKG_CONFIG, pkg-config)
|
||||
|
||||
# Checks for header files.
|
||||
|
@ -38,6 +38,7 @@ AC_TYPE_UINT32_T
|
|||
AC_TYPE_UINT64_T
|
||||
AC_TYPE_INT32_T
|
||||
|
||||
|
||||
# Debug support (default:no)
|
||||
AC_ARG_ENABLE([debug],AS_HELP_STRING([--enable-debug],[Enable debug output]),[enable_debug=$enableval],[enable_debug="no"])
|
||||
|
||||
|
@ -101,11 +102,34 @@ then
|
|||
fi
|
||||
AM_CONDITIONAL(DOC_ENABLED, [test x"$enable_doc" = xyes])
|
||||
|
||||
AC_ARG_WITH([os-version], [AS_HELP_STRING([--with-os-version], [For FreeBSD users, use this option to override the detected OSVERSION.])])
|
||||
|
||||
case "$build_os" in
|
||||
freebsd*)
|
||||
AC_MSG_CHECKING([the FreeBSD operating system release])
|
||||
if test -n "$with_os_version"; then
|
||||
OSVERSION="$with_os_version"
|
||||
else
|
||||
OSVERSION=`/sbin/sysctl -n kern.osreldate`
|
||||
fi
|
||||
AC_MSG_RESULT([$OSVERSION])
|
||||
AC_MSG_CHECKING([which usb library to use])
|
||||
if test "$OSVERSION" -lt "800069"; then
|
||||
system_has_libusb="no"
|
||||
AC_MSG_RESULT([devel/libusb])
|
||||
else
|
||||
system_has_libusb="yes"
|
||||
AC_MSG_RESULT(system)
|
||||
LIBUSB_LIBS="-lusb"
|
||||
fi
|
||||
esac
|
||||
|
||||
|
||||
# Dependencies
|
||||
PKG_CONFIG_REQUIRES=""
|
||||
## libusb
|
||||
if test "x$enable_libusb" = "xyes"; then
|
||||
if test x"$system_has_libusb" != "xyes"; then
|
||||
if test x"$PKG_CONFIG" = "x"; then
|
||||
AC_PATH_PROG(LIBUSB_CONFIG,libusb-config)
|
||||
if test x"$LIBUSB_CONFIG" = "x" ; then
|
||||
|
@ -126,6 +150,7 @@ if test "x$enable_libusb" = "xyes"; then
|
|||
if test x"$WITH_USB" = "x0"; then
|
||||
AC_MSG_ERROR([libusb is mandatory.])
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(LIBUSB_LIBS)
|
||||
AC_SUBST(LIBUSB_CFLAGS)
|
||||
fi
|
||||
|
@ -165,10 +190,14 @@ AC_MSG_RESULT($enable_std_c99)
|
|||
if test x"$enable_std_c99" != "xno"
|
||||
then
|
||||
CFLAGS="$CFLAGS -std=c99"
|
||||
|
||||
# Workarounds for libusb in c99
|
||||
CFLAGS="$CFLAGS -Du_int8_t=uint8_t -Du_int16_t=uint16_t"
|
||||
fi
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
src/lib/chips/Makefile
|
||||
src/lib/buses/Makefile
|
||||
src/lib/drivers/Makefile
|
||||
src/lib/Makefile
|
||||
|
|
2
debian/rules
vendored
2
debian/rules
vendored
|
@ -106,7 +106,7 @@ binary-arch: build install
|
|||
dh_fixperms
|
||||
# dh_perl
|
||||
# dh_python
|
||||
# dh_makeshlibs
|
||||
dh_makeshlibs
|
||||
dh_installdeb
|
||||
$(DH_SHLIBDEPS)
|
||||
dh_gencontrol
|
||||
|
|
693
install-sh
693
install-sh
|
@ -1,276 +1,519 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5 (mit/util/scripts/install.sh).
|
||||
|
||||
scriptversion=2006-12-25.00
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright 1991 by the Massachusetts Institute of Technology
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission to use, copy, modify, distribute, and sell this software and its
|
||||
# documentation for any purpose is hereby granted without fee, provided that
|
||||
# the above copyright notice appear in all copies and that both that
|
||||
# copyright notice and this permission notice appear in supporting
|
||||
# documentation, and that the name of M.I.T. not be used in advertising or
|
||||
# publicity pertaining to distribution of the software without specific,
|
||||
# written prior permission. M.I.T. makes no representations about the
|
||||
# suitability of this software for any purpose. It is provided "as is"
|
||||
# without express or implied warranty.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch. It can only install one file at a time, a restriction
|
||||
# shared with many OS's install programs.
|
||||
# from scratch.
|
||||
|
||||
nl='
|
||||
'
|
||||
IFS=" "" $nl"
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
doit=${DOITPROG-}
|
||||
if test -z "$doit"; then
|
||||
doit_exec=exec
|
||||
else
|
||||
doit_exec=$doit
|
||||
fi
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
posix_glob='?'
|
||||
initialize_posix_glob='
|
||||
test "$posix_glob" != "?" || {
|
||||
if (set -f) 2>/dev/null; then
|
||||
posix_glob=
|
||||
else
|
||||
posix_glob=:
|
||||
fi
|
||||
}
|
||||
'
|
||||
|
||||
transformbasename=""
|
||||
transform_arg=""
|
||||
instcmd="$mvprog"
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=""
|
||||
chgrpcmd=""
|
||||
stripcmd=""
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=""
|
||||
dst=""
|
||||
dir_arg=""
|
||||
stripcmd=
|
||||
|
||||
while [ x"$1" != x ]; do
|
||||
case $1 in
|
||||
-c) instcmd=$cpprog
|
||||
shift
|
||||
continue;;
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
copy_on_change=false
|
||||
no_target_directory=
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-s) stripcmd=$stripprog
|
||||
shift
|
||||
continue;;
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||
shift
|
||||
continue;;
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||
shift
|
||||
continue;;
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
*) if [ x"$src" = x ]
|
||||
then
|
||||
src=$1
|
||||
else
|
||||
# this colon is to work around a 386BSD /bin/sh bug
|
||||
:
|
||||
dst=$1
|
||||
fi
|
||||
shift
|
||||
continue;;
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *' '* | *'
|
||||
'* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t) dst_arg=$2
|
||||
shift;;
|
||||
|
||||
-T) no_target_directory=true;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call `install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
trap '(exit $?); exit' 1 2 13 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names starting with `-'.
|
||||
case $src in
|
||||
-*) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dst=$dst_arg
|
||||
# Protect names starting with `-'.
|
||||
case $dst in
|
||||
-*) dst=./$dst;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$src" = x ]
|
||||
then
|
||||
echo "$0: no input file specified" >&2
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test -n "$no_target_directory"; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
else
|
||||
:
|
||||
fi
|
||||
fi
|
||||
dstdir=$dst
|
||||
dst=$dstdir/`basename "$src"`
|
||||
dstdir_status=0
|
||||
else
|
||||
# Prefer dirname, but fall back on a substitute if dirname fails.
|
||||
dstdir=`
|
||||
(dirname "$dst") 2>/dev/null ||
|
||||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$dst" : 'X\(//\)[^/]' \| \
|
||||
X"$dst" : 'X\(//\)$' \| \
|
||||
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
echo X"$dst" |
|
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)[^/].*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\).*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
s/.*/./; q'
|
||||
`
|
||||
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "$dst" ]; then
|
||||
instcmd=:
|
||||
chmodcmd=""
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
instcmd=$mkdirprog
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f "$src" ] || [ -d "$src" ]
|
||||
then
|
||||
:
|
||||
else
|
||||
echo "$0: $src does not exist" >&2
|
||||
exit 1
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "$0: no destination specified" >&2
|
||||
exit 1
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
if (umask $mkdir_umask &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writeable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/d" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
-*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
eval "$initialize_posix_glob"
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
$posix_glob set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
$posix_glob set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test -z "$d" && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
:
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
# If destination is a directory, append the input filename; if your system
|
||||
# does not like double slashes in filenames, you may need to add some logic
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "$dst" ]
|
||||
then
|
||||
dst=$dst/`basename "$src"`
|
||||
else
|
||||
:
|
||||
fi
|
||||
fi
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
## this sed command emulates the dirname command
|
||||
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-$defaultIFS}"
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
oIFS=$IFS
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS=$oIFS
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
pathcomp=''
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
pathcomp=$pathcomp$1
|
||||
shift
|
||||
eval "$initialize_posix_glob" &&
|
||||
$posix_glob set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
$posix_glob set +f &&
|
||||
|
||||
if [ ! -d "$pathcomp" ] ;
|
||||
then
|
||||
$mkdirprog "$pathcomp"
|
||||
else
|
||||
:
|
||||
fi
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
pathcomp=$pathcomp/
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]
|
||||
then
|
||||
$doit $instcmd "$dst" &&
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
|
||||
else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename "$dst"`
|
||||
else
|
||||
dstfile=`basename "$dst" $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename "$dst"`
|
||||
else
|
||||
:
|
||||
fi
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
|
||||
dsttmp=$dstdir/#inst.$$#
|
||||
rmtmp=$dstdir/#rm.$$#
|
||||
|
||||
# Trap to clean up temp files at exit.
|
||||
|
||||
trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
|
||||
trap '(exit $?); exit' 1 2 13 15
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
|
||||
$doit $instcmd "$src" "$dsttmp" &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits
|
||||
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
|
||||
|
||||
# Now remove or move aside any old file at destination location. We try this
|
||||
# two ways since rm can't unlink itself on some systems and the destination
|
||||
# file might be busy for other reasons. In this case, the final cleanup
|
||||
# might fail but the new file should still install successfully.
|
||||
|
||||
{
|
||||
if [ -f "$dstdir/$dstfile" ]
|
||||
then
|
||||
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
|
||||
$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
|
||||
{
|
||||
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
|
||||
(exit 1); exit
|
||||
}
|
||||
else
|
||||
:
|
||||
fi
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
|
||||
|
||||
fi &&
|
||||
|
||||
# The final little trick to "correctly" pass the exit status to the exit trap.
|
||||
|
||||
{
|
||||
(exit 0); exit
|
||||
}
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
||||
|
|
197
missing
197
missing
|
@ -1,6 +1,10 @@
|
|||
#! /bin/sh
|
||||
# Common stub for a few missing GNU programs while installing.
|
||||
# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||
|
||||
scriptversion=2006-05-10.23
|
||||
|
||||
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
|
||||
# Free Software Foundation, Inc.
|
||||
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
@ -15,8 +19,8 @@
|
|||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
# 02111-1307, USA.
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
|
@ -29,6 +33,8 @@ if test $# -eq 0; then
|
|||
fi
|
||||
|
||||
run=:
|
||||
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
|
||||
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
|
||||
|
||||
# In the cases where this matters, `missing' is being run in the
|
||||
# srcdir already.
|
||||
|
@ -38,18 +44,24 @@ else
|
|||
configure_ac=configure.in
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
msg="missing on your system"
|
||||
|
||||
case $1 in
|
||||
--run)
|
||||
# Try to run requested program, and just exit if it succeeds.
|
||||
run=
|
||||
shift
|
||||
"$@" && exit 0
|
||||
# Exit code 63 means version mismatch. This often happens
|
||||
# when the user try to use an ancient version of a tool on
|
||||
# a file that requires a minimum version. In this case we
|
||||
# we should proceed has if the program had been absent, or
|
||||
# if --run hadn't been passed.
|
||||
if test $? = 63; then
|
||||
run=:
|
||||
msg="probably too old"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If it does not exist, or fails to run (possibly an outdated version),
|
||||
# try to emulate it.
|
||||
case "$1" in
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "\
|
||||
|
@ -67,6 +79,7 @@ Supported PROGRAM values:
|
|||
aclocal touch file \`aclocal.m4'
|
||||
autoconf touch file \`configure'
|
||||
autoheader touch file \`config.h.in'
|
||||
autom4te touch the output file, or create a stub one
|
||||
automake touch all \`Makefile.in' files
|
||||
bison create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||
flex create \`lex.yy.c', if possible, from existing .c
|
||||
|
@ -74,11 +87,15 @@ Supported PROGRAM values:
|
|||
lex create \`lex.yy.c', if possible, from existing .c
|
||||
makeinfo touch the output file
|
||||
tar try tar, gnutar, gtar, then tar without non-portable flags
|
||||
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
|
||||
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||
|
||||
Send bug reports to <bug-automake@gnu.org>."
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||
echo "missing 0.4 - GNU automake"
|
||||
echo "missing $scriptversion (GNU Automake)"
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-*)
|
||||
|
@ -87,14 +104,44 @@ Supported PROGRAM values:
|
|||
exit 1
|
||||
;;
|
||||
|
||||
aclocal*)
|
||||
esac
|
||||
|
||||
# Now exit if we have it, but it failed. Also exit now if we
|
||||
# don't have it and --version was passed (most likely to detect
|
||||
# the program).
|
||||
case $1 in
|
||||
lex|yacc)
|
||||
# Not GNU programs, they don't have --version.
|
||||
;;
|
||||
|
||||
tar)
|
||||
if test -n "$run"; then
|
||||
echo 1>&2 "ERROR: \`tar' requires --run"
|
||||
exit 1
|
||||
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||
# We have it, but it failed.
|
||||
exit 1
|
||||
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
|
||||
# Could not run --version or --help. This is probably someone
|
||||
# running `$TOOL --version' or `$TOOL --help' to check whether
|
||||
# $TOOL exists and not knowing $TOOL uses missing.
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If it does not exist, or fails to run (possibly an outdated version),
|
||||
# try to emulate it.
|
||||
case $1 in
|
||||
aclocal*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
|
||||
to install the \`Automake' and \`Perl' packages. Grab them from
|
||||
any GNU archive site."
|
||||
|
@ -102,13 +149,8 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
|||
;;
|
||||
|
||||
autoconf)
|
||||
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||
# We have it, but it failed.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`${configure_ac}'. You might want to install the
|
||||
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
|
||||
archive site."
|
||||
|
@ -116,13 +158,8 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
|||
;;
|
||||
|
||||
autoheader)
|
||||
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||
# We have it, but it failed.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`acconfig.h' or \`${configure_ac}'. You might want
|
||||
to install the \`Autoconf' and \`GNU m4' packages. Grab them
|
||||
from any GNU archive site."
|
||||
|
@ -130,7 +167,7 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
|||
test -z "$files" && files="config.h"
|
||||
touch_files=
|
||||
for f in $files; do
|
||||
case "$f" in
|
||||
case $f in
|
||||
*:*) touch_files="$touch_files "`echo "$f" |
|
||||
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
|
||||
*) touch_files="$touch_files $f.in";;
|
||||
|
@ -140,13 +177,8 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
|||
;;
|
||||
|
||||
automake*)
|
||||
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||
# We have it, but it failed.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
|
||||
You might want to install the \`Automake' and \`Perl' packages.
|
||||
Grab them from any GNU archive site."
|
||||
|
@ -156,20 +188,15 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
|||
;;
|
||||
|
||||
autom4te)
|
||||
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||
# We have it, but it failed.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is needed, and you do not seem to have it handy on your
|
||||
system. You might have modified some files without having the
|
||||
WARNING: \`$1' is needed, but is $msg.
|
||||
You might have modified some files without having the
|
||||
proper tools for further handling them.
|
||||
You can get \`$1Help2man' as part of \`Autoconf' from any GNU
|
||||
You can get \`$1' as part of \`Autoconf' from any GNU
|
||||
archive site."
|
||||
|
||||
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
|
||||
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
|
||||
file=`echo "$*" | sed -n "$sed_output"`
|
||||
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
|
||||
if test -f "$file"; then
|
||||
touch $file
|
||||
else
|
||||
|
@ -185,74 +212,67 @@ WARNING: \`$1' is needed, and you do not seem to have it handy on your
|
|||
|
||||
bison|yacc)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
WARNING: \`$1' $msg. You should only need it if
|
||||
you modified a \`.y' file. You may need the \`Bison' package
|
||||
in order for those modifications to take effect. You can get
|
||||
\`Bison' from any GNU archive site."
|
||||
rm -f y.tab.c y.tab.h
|
||||
if [ $# -ne 1 ]; then
|
||||
if test $# -ne 1; then
|
||||
eval LASTARG="\${$#}"
|
||||
case "$LASTARG" in
|
||||
case $LASTARG in
|
||||
*.y)
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
|
||||
if [ -f "$SRCFILE" ]; then
|
||||
if test -f "$SRCFILE"; then
|
||||
cp "$SRCFILE" y.tab.c
|
||||
fi
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
|
||||
if [ -f "$SRCFILE" ]; then
|
||||
if test -f "$SRCFILE"; then
|
||||
cp "$SRCFILE" y.tab.h
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ ! -f y.tab.h ]; then
|
||||
if test ! -f y.tab.h; then
|
||||
echo >y.tab.h
|
||||
fi
|
||||
if [ ! -f y.tab.c ]; then
|
||||
if test ! -f y.tab.c; then
|
||||
echo 'main() { return 0; }' >y.tab.c
|
||||
fi
|
||||
;;
|
||||
|
||||
lex|flex)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified a \`.l' file. You may need the \`Flex' package
|
||||
in order for those modifications to take effect. You can get
|
||||
\`Flex' from any GNU archive site."
|
||||
rm -f lex.yy.c
|
||||
if [ $# -ne 1 ]; then
|
||||
if test $# -ne 1; then
|
||||
eval LASTARG="\${$#}"
|
||||
case "$LASTARG" in
|
||||
case $LASTARG in
|
||||
*.l)
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
|
||||
if [ -f "$SRCFILE" ]; then
|
||||
if test -f "$SRCFILE"; then
|
||||
cp "$SRCFILE" lex.yy.c
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ ! -f lex.yy.c ]; then
|
||||
if test ! -f lex.yy.c; then
|
||||
echo 'main() { return 0; }' >lex.yy.c
|
||||
fi
|
||||
;;
|
||||
|
||||
help2man)
|
||||
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||
# We have it, but it failed.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified a dependency of a manual page. You may need the
|
||||
\`Help2man' package in order for those modifications to take
|
||||
effect. You can get \`Help2man' from any GNU archive site."
|
||||
|
||||
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||
if test -z "$file"; then
|
||||
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
|
||||
fi
|
||||
if [ -f "$file" ]; then
|
||||
file=`echo "$*" | sed -n "$sed_output"`
|
||||
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
|
||||
if test -f "$file"; then
|
||||
touch $file
|
||||
else
|
||||
test -z "$file" || exec >$file
|
||||
|
@ -262,32 +282,36 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
|||
;;
|
||||
|
||||
makeinfo)
|
||||
if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
|
||||
# We have makeinfo, but it failed.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is missing on your system. You should only need it if
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified a \`.texi' or \`.texinfo' file, or any other file
|
||||
indirectly affecting the aspect of the manual. The spurious
|
||||
call might also be the consequence of using a buggy \`make' (AIX,
|
||||
DU, IRIX). You might want to install the \`Texinfo' package or
|
||||
the \`GNU make' package. Grab either from any GNU archive site."
|
||||
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||
# The file to touch is that specified with -o ...
|
||||
file=`echo "$*" | sed -n "$sed_output"`
|
||||
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
|
||||
if test -z "$file"; then
|
||||
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
|
||||
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
|
||||
# ... or it is the one specified with @setfilename ...
|
||||
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
|
||||
file=`sed -n '
|
||||
/^@setfilename/{
|
||||
s/.* \([^ ]*\) *$/\1/
|
||||
p
|
||||
q
|
||||
}' $infile`
|
||||
# ... or it is derived from the source name (dir/f.texi becomes f.info)
|
||||
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
|
||||
fi
|
||||
# If the file does not exist, the user really needs makeinfo;
|
||||
# let's fail without touching anything.
|
||||
test -f $file || exit 1
|
||||
touch $file
|
||||
;;
|
||||
|
||||
tar)
|
||||
shift
|
||||
if test -n "$run"; then
|
||||
echo 1>&2 "ERROR: \`tar' requires --run"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# We have already tried tar in the generic part.
|
||||
# Look for gnutar/gtar before invocation to avoid ugly error
|
||||
|
@ -300,13 +324,13 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
|||
fi
|
||||
firstarg="$1"
|
||||
if shift; then
|
||||
case "$firstarg" in
|
||||
case $firstarg in
|
||||
*o*)
|
||||
firstarg=`echo "$firstarg" | sed s/o//`
|
||||
tar "$firstarg" "$@" && exit 0
|
||||
;;
|
||||
esac
|
||||
case "$firstarg" in
|
||||
case $firstarg in
|
||||
*h*)
|
||||
firstarg=`echo "$firstarg" | sed s/h//`
|
||||
tar "$firstarg" "$@" && exit 0
|
||||
|
@ -323,10 +347,10 @@ WARNING: I can't seem to be able to run \`tar' with the given arguments.
|
|||
|
||||
*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is needed, and you do not seem to have it handy on your
|
||||
system. You might have modified some files without having the
|
||||
WARNING: \`$1' is needed, and is $msg.
|
||||
You might have modified some files without having the
|
||||
proper tools for further handling them. Check the \`README' file,
|
||||
it often tells you about the needed prerequirements for installing
|
||||
it often tells you about the needed prerequisites for installing
|
||||
this package. You may also peek at any GNU archive site, in case
|
||||
some other package would contain this missing \`$1' program."
|
||||
exit 1
|
||||
|
@ -334,3 +358,10 @@ WARNING: \`$1' is needed, and you do not seem to have it handy on your
|
|||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#ifndef _LIBNFC_MIFARE_TAG_H_
|
||||
#define _LIBNFC_MIFARE_TAG_H_
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
typedef struct {
|
||||
byte_t abtUID[4];
|
||||
byte_t btBCC;
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#ifndef _LIBNFC_MIFARE_UL_TAG_H_
|
||||
#define _LIBNFC_MIFARE_UL_TAG_H_
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
typedef struct {
|
||||
byte_t sn0[3];
|
||||
byte_t btBCC0;
|
||||
|
|
|
@ -30,17 +30,19 @@
|
|||
|
||||
#include <nfc.h>
|
||||
|
||||
#include "messages.h"
|
||||
#include "nfc-messages.h"
|
||||
#include "bitutils.h"
|
||||
|
||||
#define SAK_FLAG_ATS_SUPPORTED 0x20
|
||||
|
||||
#define MAX_FRAME_LEN 264
|
||||
|
||||
static byte_t abtRx[MAX_FRAME_LEN];
|
||||
static size_t szRxBits;
|
||||
static size_t szRxLen;
|
||||
static byte_t abtUid[10];
|
||||
static size_t szUidLen = 4;
|
||||
static dev_info* pdi;
|
||||
static nfc_device_t* pnd;
|
||||
|
||||
bool quiet_output = false;
|
||||
|
||||
|
@ -61,7 +63,7 @@ bool transmit_bits(const byte_t* pbtTx, const size_t szTxBits)
|
|||
}
|
||||
|
||||
// Transmit the bit frame command, we don't use the arbitrary parity feature
|
||||
if (!nfc_initiator_transceive_bits(pdi,pbtTx,szTxBits,NULL,abtRx,&szRxBits,NULL)) return false;
|
||||
if (!nfc_initiator_transceive_bits(pnd,pbtTx,szTxBits,NULL,abtRx,&szRxBits,NULL)) return false;
|
||||
|
||||
// Show received answer
|
||||
if(!quiet_output)
|
||||
|
@ -85,7 +87,7 @@ bool transmit_bytes(const byte_t* pbtTx, const size_t szTxLen)
|
|||
}
|
||||
|
||||
// Transmit the command bytes
|
||||
if (!nfc_initiator_transceive_bytes(pdi,pbtTx,szTxLen,abtRx,&szRxLen)) return false;
|
||||
if (!nfc_initiator_transceive_bytes(pnd,pbtTx,szTxLen,abtRx,&szRxLen)) return false;
|
||||
|
||||
// Show received answer
|
||||
if(!quiet_output)
|
||||
|
@ -126,32 +128,32 @@ int main(int argc,char* argv[])
|
|||
}
|
||||
|
||||
// Try to open the NFC reader
|
||||
pdi = nfc_connect(NULL);
|
||||
pnd = nfc_connect(NULL);
|
||||
|
||||
if (!pdi)
|
||||
if (!pnd)
|
||||
{
|
||||
printf("Error connecting NFC reader\n");
|
||||
return 1;
|
||||
}
|
||||
nfc_initiator_init(pdi);
|
||||
nfc_initiator_init(pnd);
|
||||
|
||||
// Drop the field for a while
|
||||
nfc_configure(pdi,DCO_ACTIVATE_FIELD,false);
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,false);
|
||||
|
||||
// Configure the CRC and Parity settings
|
||||
nfc_configure(pdi,DCO_HANDLE_CRC,false);
|
||||
nfc_configure(pdi,DCO_HANDLE_PARITY,true);
|
||||
nfc_configure(pnd,NDO_HANDLE_CRC,false);
|
||||
nfc_configure(pnd,NDO_HANDLE_PARITY,true);
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
nfc_configure(pdi,DCO_ACTIVATE_FIELD,true);
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,true);
|
||||
|
||||
printf("\nConnected to NFC reader: %s\n\n",pdi->acName);
|
||||
printf("\nConnected to NFC reader: %s\n\n",pnd->acName);
|
||||
|
||||
// Send the 7 bits request command specified in ISO 14443A (0x26)
|
||||
if (!transmit_bits(abtReqa,7))
|
||||
{
|
||||
printf("Error: No tag available\n");
|
||||
nfc_disconnect(pdi);
|
||||
nfc_disconnect(pnd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -198,6 +200,6 @@ int main(int argc,char* argv[])
|
|||
printf("%014llx\n",swap_endian64(abtUid)&0x00ffffffffffffffull);
|
||||
}
|
||||
|
||||
nfc_disconnect(pdi);
|
||||
nfc_disconnect(pnd);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -29,12 +29,14 @@
|
|||
|
||||
#include <nfc.h>
|
||||
|
||||
#include "messages.h"
|
||||
#include "nfc-messages.h"
|
||||
#include "bitutils.h"
|
||||
|
||||
#define MAX_FRAME_LEN 264
|
||||
|
||||
static byte_t abtRecv[MAX_FRAME_LEN];
|
||||
static size_t szRecvBits;
|
||||
static dev_info* pdi;
|
||||
static nfc_device_t* pnd;
|
||||
|
||||
// ISO14443A Anti-Collision response
|
||||
byte_t abtAtqa [2] = { 0x04,0x00 };
|
||||
|
@ -85,20 +87,20 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
// Try to open the NFC reader
|
||||
pdi = nfc_connect(NULL);
|
||||
pnd = nfc_connect(NULL);
|
||||
|
||||
if (pdi == INVALID_DEVICE_INFO)
|
||||
if (pnd == NULL)
|
||||
{
|
||||
printf("Error connecting NFC reader\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
printf("[+] Connected to NFC reader: %s\n",pdi->acName);
|
||||
printf("[+] Connected to NFC reader: %s\n",pnd->acName);
|
||||
printf("[+] Try to break out the auto-emulation, this requires a second reader!\n");
|
||||
printf("[+] To do this, please send any command after the anti-collision\n");
|
||||
printf("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
|
||||
if (!nfc_target_init(pdi,abtRecv,&szRecvBits))
|
||||
if (!nfc_target_init(pnd,abtRecv,&szRecvBits))
|
||||
{
|
||||
printf("Error: Could not come out of auto-emulation, no command was received\n");
|
||||
return 1;
|
||||
|
@ -106,14 +108,14 @@ int main(int argc, char *argv[])
|
|||
printf("[+] Received initiator command: ");
|
||||
print_hex_bits(abtRecv,szRecvBits);
|
||||
printf("[+] Configuring communication\n");
|
||||
nfc_configure(pdi,DCO_HANDLE_CRC,false);
|
||||
nfc_configure(pdi,DCO_HANDLE_PARITY,true);
|
||||
nfc_configure(pnd,NDO_HANDLE_CRC,false);
|
||||
nfc_configure(pnd,NDO_HANDLE_PARITY,true);
|
||||
printf("[+] Done, the emulated tag is initialized with UID: %02X%02X%02X%02X\n\n",abtUidBcc[0],abtUidBcc[1],abtUidBcc[2],abtUidBcc[3]);
|
||||
|
||||
while(true)
|
||||
{
|
||||
// Test if we received a frame
|
||||
if (nfc_target_receive_bits(pdi,abtRecv,&szRecvBits,NULL))
|
||||
if (nfc_target_receive_bits(pnd,abtRecv,&szRecvBits,NULL))
|
||||
{
|
||||
// Prepare the command to send back for the anti-collision request
|
||||
switch(szRecvBits)
|
||||
|
@ -150,7 +152,7 @@ int main(int argc, char *argv[])
|
|||
if(szTxBits)
|
||||
{
|
||||
// Send and print the command to the screen
|
||||
nfc_target_send_bits(pdi,pbtTx,szTxBits,NULL);
|
||||
nfc_target_send_bits(pnd,pbtTx,szTxBits,NULL);
|
||||
if(!quiet_output)
|
||||
{
|
||||
printf("T: ");
|
||||
|
@ -160,6 +162,6 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
nfc_disconnect(pdi);
|
||||
nfc_disconnect(pnd);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,18 +29,29 @@
|
|||
|
||||
#include <nfc.h>
|
||||
|
||||
#include "messages.h"
|
||||
#include "nfc-messages.h"
|
||||
#include "bitutils.h"
|
||||
|
||||
static dev_info* pdi;
|
||||
#define MAX_DEVICE_COUNT 16
|
||||
|
||||
static nfc_device_t* pnd;
|
||||
static byte_t abtFelica[5] = { 0x00, 0xff, 0xff, 0x00, 0x00 };
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
tag_info ti;
|
||||
size_t szFound;
|
||||
int i;
|
||||
nfc_target_info_t nti;
|
||||
nfc_device_desc_t *pnddDevices;
|
||||
|
||||
// Try to open the NFC device
|
||||
pdi = nfc_connect(NULL);
|
||||
// Display libnfc version
|
||||
const char* acLibnfcVersion = nfc_version();
|
||||
printf("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||
|
||||
// Lazy way to open an NFC device
|
||||
/*
|
||||
pnd = nfc_connect(NULL);
|
||||
*/
|
||||
|
||||
// If specific device is wanted, i.e. an ARYGON device on /dev/ttyUSB0
|
||||
/*
|
||||
|
@ -49,74 +60,94 @@ int main(int argc, const char* argv[])
|
|||
ndd.pcPort = "/dev/ttyUSB0";
|
||||
ndd.uiSpeed = 115200;
|
||||
|
||||
pdi = nfc_connect(&ndd);
|
||||
pnd = nfc_connect(&ndd);
|
||||
*/
|
||||
|
||||
if (pdi == INVALID_DEVICE_INFO)
|
||||
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices))))
|
||||
{
|
||||
ERR("Unable to connect to NFC device.");
|
||||
return 1;
|
||||
fprintf (stderr, "malloc() failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
nfc_initiator_init(pdi);
|
||||
|
||||
// Drop the field for a while
|
||||
nfc_configure(pdi,DCO_ACTIVATE_FIELD,false);
|
||||
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound);
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
nfc_configure(pdi,DCO_INFINITE_SELECT,false);
|
||||
|
||||
// Configure the CRC and Parity settings
|
||||
nfc_configure(pdi,DCO_HANDLE_CRC,true);
|
||||
nfc_configure(pdi,DCO_HANDLE_PARITY,true);
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
nfc_configure(pdi,DCO_ACTIVATE_FIELD,true);
|
||||
|
||||
printf("Connected to NFC reader: %s\n\n",pdi->acName);
|
||||
|
||||
// Poll for a ISO14443A (MIFARE) tag
|
||||
if (nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti))
|
||||
if (szFound == 0)
|
||||
{
|
||||
printf("The following (NFC) ISO14443A tag was found:\n\n");
|
||||
printf(" ATQA (SENS_RES): "); print_hex(ti.tia.abtAtqa,2);
|
||||
printf(" UID (NFCID%c): ",(ti.tia.abtUid[0]==0x08?'3':'1')); print_hex(ti.tia.abtUid,ti.tia.szUidLen);
|
||||
printf(" SAK (SEL_RES): "); print_hex(&ti.tia.btSak,1);
|
||||
if (ti.tia.szAtsLen)
|
||||
INFO("%s", "No device found.");
|
||||
}
|
||||
|
||||
for (i = 0; i < szFound; i++)
|
||||
{
|
||||
pnd = nfc_connect(&(pnddDevices[i]));
|
||||
|
||||
|
||||
if (pnd == NULL)
|
||||
{
|
||||
printf(" ATS (ATR): ");
|
||||
print_hex(ti.tia.abtAts,ti.tia.szAtsLen);
|
||||
ERR("%s", "Unable to connect to NFC device.");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
nfc_initiator_init(pnd);
|
||||
|
||||
// Poll for a Felica tag
|
||||
if (nfc_initiator_select_tag(pdi,IM_FELICA_212,abtFelica,5,&ti) || nfc_initiator_select_tag(pdi,IM_FELICA_424,abtFelica,5,&ti))
|
||||
{
|
||||
printf("The following (NFC) Felica tag was found:\n\n");
|
||||
printf("%18s","ID (NFCID2): "); print_hex(ti.tif.abtId,8);
|
||||
printf("%18s","Parameter (PAD): "); print_hex(ti.tif.abtPad,8);
|
||||
}
|
||||
// Drop the field for a while
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,false);
|
||||
|
||||
// Poll for a ISO14443B tag
|
||||
if (nfc_initiator_select_tag(pdi,IM_ISO14443B_106,(byte_t*)"\x00",1,&ti))
|
||||
{
|
||||
printf("The following (NFC) ISO14443-B tag was found:\n\n");
|
||||
printf(" ATQB: "); print_hex(ti.tib.abtAtqb,12);
|
||||
printf(" ID: "); print_hex(ti.tib.abtId,4);
|
||||
printf(" CID: %02x\n",ti.tib.btCid);
|
||||
if (ti.tib.szInfLen>0)
|
||||
// Let the reader only try once to find a tag
|
||||
nfc_configure(pnd,NDO_INFINITE_SELECT,false);
|
||||
|
||||
// Configure the CRC and Parity settings
|
||||
nfc_configure(pnd,NDO_HANDLE_CRC,true);
|
||||
nfc_configure(pnd,NDO_HANDLE_PARITY,true);
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,true);
|
||||
|
||||
printf("Connected to NFC reader: %s\n\n",pnd->acName);
|
||||
|
||||
// Poll for a ISO14443A (MIFARE) tag
|
||||
if (nfc_initiator_select_tag(pnd,NM_ISO14443A_106,NULL,0,&nti))
|
||||
{
|
||||
printf(" INF: "); print_hex(ti.tib.abtInf,ti.tib.szInfLen);
|
||||
printf("The following (NFC) ISO14443A tag was found:\n\n");
|
||||
printf(" ATQA (SENS_RES): "); print_hex(nti.nai.abtAtqa,2);
|
||||
printf(" UID (NFCID%c): ",(nti.nai.abtUid[0]==0x08?'3':'1')); print_hex(nti.nai.abtUid,nti.nai.szUidLen);
|
||||
printf(" SAK (SEL_RES): "); print_hex(&nti.nai.btSak,1);
|
||||
if (nti.nai.szAtsLen)
|
||||
{
|
||||
printf(" ATS (ATR): ");
|
||||
print_hex(nti.nai.abtAts,nti.nai.szAtsLen);
|
||||
}
|
||||
}
|
||||
printf("PARAMS: %02x %02x %02x %02x\n",ti.tib.btParam1,ti.tib.btParam2,ti.tib.btParam3,ti.tib.btParam4);
|
||||
}
|
||||
|
||||
// Poll for a Jewel tag
|
||||
if (nfc_initiator_select_tag(pdi,IM_JEWEL_106,NULL,0,&ti))
|
||||
{
|
||||
// No test results yet
|
||||
printf("jewel\n");
|
||||
}
|
||||
// Poll for a Felica tag
|
||||
if (nfc_initiator_select_tag(pnd,NM_FELICA_212,abtFelica,5,&nti) || nfc_initiator_select_tag(pnd,NM_FELICA_424,abtFelica,5,&nti))
|
||||
{
|
||||
printf("The following (NFC) Felica tag was found:\n\n");
|
||||
printf("%18s","ID (NFCID2): "); print_hex(nti.nfi.abtId,8);
|
||||
printf("%18s","Parameter (PAD): "); print_hex(nti.nfi.abtPad,8);
|
||||
}
|
||||
|
||||
nfc_disconnect(pdi);
|
||||
return 1;
|
||||
// Poll for a ISO14443B tag
|
||||
if (nfc_initiator_select_tag(pnd,NM_ISO14443B_106,(byte_t*)"\x00",1,&nti))
|
||||
{
|
||||
printf("The following (NFC) ISO14443-B tag was found:\n\n");
|
||||
printf(" ATQB: "); print_hex(nti.nbi.abtAtqb,12);
|
||||
printf(" ID: "); print_hex(nti.nbi.abtId,4);
|
||||
printf(" CID: %02x\n",nti.nbi.btCid);
|
||||
if (nti.nbi.szInfLen>0)
|
||||
{
|
||||
printf(" INF: "); print_hex(nti.nbi.abtInf,nti.nbi.szInfLen);
|
||||
}
|
||||
printf("PARAMS: %02x %02x %02x %02x\n",nti.nbi.btParam1,nti.nbi.btParam2,nti.nbi.btParam3,nti.nbi.btParam4);
|
||||
}
|
||||
|
||||
// Poll for a Jewel tag
|
||||
if (nfc_initiator_select_tag(pnd,NM_JEWEL_106,NULL,0,&nti))
|
||||
{
|
||||
// No test results yet
|
||||
printf("jewel\n");
|
||||
}
|
||||
|
||||
nfc_disconnect(pnd);
|
||||
}
|
||||
|
||||
free (pnddDevices);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
#include "mifaretag.h"
|
||||
#include "bitutils.h"
|
||||
|
||||
static dev_info* pdi;
|
||||
static tag_info ti;
|
||||
static nfc_device_t* pnd;
|
||||
static nfc_target_info_t nti;
|
||||
static mifare_param mp;
|
||||
static mifare_tag mtKeys;
|
||||
static mifare_tag mtDump;
|
||||
|
@ -89,7 +89,7 @@ bool authenticate(uint32_t uiBlock)
|
|||
if (bUseKeyFile)
|
||||
{
|
||||
// Set the authentication information (uid)
|
||||
memcpy(mp.mpa.abtUid,ti.tia.abtUid,4);
|
||||
memcpy(mp.mpa.abtUid,nti.nai.abtUid,4);
|
||||
|
||||
// Locate the trailer (with the keys) used for this sector
|
||||
uiTrailerBlock = get_trailer_block(uiBlock);
|
||||
|
@ -105,7 +105,7 @@ bool authenticate(uint32_t uiBlock)
|
|||
}
|
||||
|
||||
// Try to authenticate for the current sector
|
||||
if (nfc_initiator_mifare_cmd(pdi,mc,uiBlock,&mp))
|
||||
if (nfc_initiator_mifare_cmd(pnd,mc,uiBlock,&mp))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -116,12 +116,12 @@ bool authenticate(uint32_t uiBlock)
|
|||
mc = (bUseKeyA) ? MC_AUTH_A : MC_AUTH_B;
|
||||
|
||||
// Set the authentication information (uid)
|
||||
memcpy(mp.mpa.abtUid,ti.tia.abtUid,4);
|
||||
memcpy(mp.mpa.abtUid,nti.nai.abtUid,4);
|
||||
|
||||
for (key_index = 0; key_index < num_keys; key_index++)
|
||||
{
|
||||
memcpy(mp.mpa.abtKey, keys + (key_index*6), 6);
|
||||
if (nfc_initiator_mifare_cmd(pdi, mc, uiBlock, &mp))
|
||||
if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp))
|
||||
{
|
||||
/**
|
||||
* @note: what about the other key?
|
||||
|
@ -134,7 +134,7 @@ bool authenticate(uint32_t uiBlock)
|
|||
return true;
|
||||
}
|
||||
|
||||
nfc_initiator_select_tag(pdi, IM_ISO14443A_106, mp.mpa.abtUid, 4, NULL);
|
||||
nfc_initiator_select_tag(pnd, NM_ISO14443A_106, mp.mpa.abtUid, 4, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,7 @@ bool read_card()
|
|||
{
|
||||
printf("x");
|
||||
// When a failure occured we need to redo the anti-collision
|
||||
if (!nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti))
|
||||
if (!nfc_initiator_select_tag(pnd,NM_ISO14443A_106,NULL,0,&nti))
|
||||
{
|
||||
printf("!\nError: tag was removed\n");
|
||||
return 1;
|
||||
|
@ -182,7 +182,7 @@ bool read_card()
|
|||
}
|
||||
|
||||
// Try to read out the trailer
|
||||
if (nfc_initiator_mifare_cmd(pdi,MC_READ,iBlock,&mp))
|
||||
if (nfc_initiator_mifare_cmd(pnd,MC_READ,iBlock,&mp))
|
||||
{
|
||||
// Copy the keys over from our key dump and store the retrieved access bits
|
||||
memcpy(mtDump.amb[iBlock].mbt.abtKeyA,mtKeys.amb[iBlock].mbt.abtKeyA,6);
|
||||
|
@ -194,7 +194,7 @@ bool read_card()
|
|||
if (!bFailure)
|
||||
{
|
||||
// Try to read out the data block
|
||||
if (nfc_initiator_mifare_cmd(pdi,MC_READ,iBlock,&mp))
|
||||
if (nfc_initiator_mifare_cmd(pnd,MC_READ,iBlock,&mp))
|
||||
{
|
||||
memcpy(mtDump.amb[iBlock].mbd.abtData,mp.mpd.abtData,16);
|
||||
} else {
|
||||
|
@ -227,7 +227,7 @@ bool write_card()
|
|||
{
|
||||
printf("x");
|
||||
// When a failure occured we need to redo the anti-collision
|
||||
if (!nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti))
|
||||
if (!nfc_initiator_select_tag(pnd,NM_ISO14443A_106,NULL,0,&nti))
|
||||
{
|
||||
printf("!\nError: tag was removed\n");
|
||||
return false;
|
||||
|
@ -258,11 +258,10 @@ bool write_card()
|
|||
memcpy(mp.mpd.abtData+10,mtDump.amb[uiBlock].mbt.abtKeyB,6);
|
||||
|
||||
// Try to write the trailer
|
||||
if (nfc_initiator_mifare_cmd(pdi,MC_WRITE,uiBlock,&mp) == false) {
|
||||
if (nfc_initiator_mifare_cmd(pnd,MC_WRITE,uiBlock,&mp) == false) {
|
||||
printf("failed to write trailer block %d \n", uiBlock);
|
||||
bFailure = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// The first block 0x00 is read only, skip this
|
||||
|
@ -273,7 +272,7 @@ bool write_card()
|
|||
{
|
||||
// Try to write the data block
|
||||
memcpy(mp.mpd.abtData,mtDump.amb[uiBlock].mbd.abtData,16);
|
||||
if (!nfc_initiator_mifare_cmd(pdi,MC_WRITE,uiBlock,&mp)) bFailure = true;
|
||||
if (!nfc_initiator_mifare_cmd(pnd,MC_WRITE,uiBlock,&mp)) bFailure = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -405,41 +404,41 @@ int main(int argc, const char* argv[])
|
|||
// printf("Successfully opened required files\n");
|
||||
|
||||
// Try to open the NFC reader
|
||||
pdi = nfc_connect(NULL);
|
||||
if (pdi == INVALID_DEVICE_INFO)
|
||||
pnd = nfc_connect(NULL);
|
||||
if (pnd == NULL)
|
||||
{
|
||||
printf("Error connecting NFC reader\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
nfc_initiator_init(pdi);
|
||||
nfc_initiator_init(pnd);
|
||||
|
||||
// Drop the field for a while
|
||||
nfc_configure(pdi,DCO_ACTIVATE_FIELD,false);
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,false);
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
nfc_configure(pdi,DCO_INFINITE_SELECT,false);
|
||||
nfc_configure(pdi,DCO_HANDLE_CRC,true);
|
||||
nfc_configure(pdi,DCO_HANDLE_PARITY,true);
|
||||
nfc_configure(pnd,NDO_INFINITE_SELECT,false);
|
||||
nfc_configure(pnd,NDO_HANDLE_CRC,true);
|
||||
nfc_configure(pnd,NDO_HANDLE_PARITY,true);
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
nfc_configure(pdi,DCO_ACTIVATE_FIELD,true);
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,true);
|
||||
|
||||
printf("Connected to NFC reader: %s\n",pdi->acName);
|
||||
printf("Connected to NFC reader: %s\n",pnd->acName);
|
||||
|
||||
// Try to find a MIFARE Classic tag
|
||||
if (!nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti))
|
||||
if (!nfc_initiator_select_tag(pnd,NM_ISO14443A_106,NULL,0,&nti))
|
||||
{
|
||||
printf("Error: no tag was found\n");
|
||||
nfc_disconnect(pdi);
|
||||
nfc_disconnect(pnd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Test if we are dealing with a MIFARE compatible tag
|
||||
if ((ti.tia.btSak & 0x08) == 0)
|
||||
if ((nti.nai.btSak & 0x08) == 0)
|
||||
{
|
||||
printf("Error: tag is not a MIFARE Classic card\n");
|
||||
nfc_disconnect(pdi);
|
||||
nfc_disconnect(pnd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -450,15 +449,15 @@ int main(int argc, const char* argv[])
|
|||
pbtUID = mtKeys.amb[0].mbm.abtUID;
|
||||
|
||||
// Compare if key dump UID is the same as the current tag UID
|
||||
if (memcmp(ti.tia.abtUid,pbtUID,4) != 0)
|
||||
if (memcmp(nti.nai.abtUid,pbtUID,4) != 0)
|
||||
{
|
||||
printf("Expected MIFARE Classic %cK card with UID: %08x\n",b4K?'4':'1',swap_endian32(pbtUID));
|
||||
}
|
||||
}
|
||||
|
||||
// Get the info from the current tag
|
||||
pbtUID = ti.tia.abtUid;
|
||||
b4K = (ti.tia.abtAtqa[1] == 0x02);
|
||||
pbtUID = nti.nai.abtUid;
|
||||
b4K = (nti.nai.abtAtqa[1] == 0x02);
|
||||
printf("Found MIFARE Classic %cK card with UID: %08x\n",b4K?'4':'1',swap_endian32(pbtUID));
|
||||
|
||||
uiBlocks = (b4K)?0xff:0x3f;
|
||||
|
@ -485,7 +484,7 @@ int main(int argc, const char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
nfc_disconnect(pdi);
|
||||
nfc_disconnect(pnd);
|
||||
break;
|
||||
|
||||
case ACTION_EXTRACT: {
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
#include "mifareultag.h"
|
||||
#include "bitutils.h"
|
||||
|
||||
static dev_info* pdi;
|
||||
static tag_info ti;
|
||||
static nfc_device_t* pnd;
|
||||
static nfc_target_info_t nti;
|
||||
static mifare_param mp;
|
||||
static mifareul_tag mtDump;
|
||||
|
||||
|
@ -48,7 +48,7 @@ bool read_card()
|
|||
// these are pages of 4 bytes each; we can read 4 pages at once.
|
||||
for (page = 0; page <= 0xF; page += 4){
|
||||
// Try to read out the data block
|
||||
if (nfc_initiator_mifare_cmd(pdi,MC_READ,page,&mp))
|
||||
if (nfc_initiator_mifare_cmd(pnd,MC_READ,page,&mp))
|
||||
{
|
||||
memcpy(mtDump.amb[page / 4].mbd.abtData, mp.mpd.abtData, 16);
|
||||
} else {
|
||||
|
@ -71,7 +71,7 @@ bool write_card()
|
|||
{
|
||||
printf("x");
|
||||
// When a failure occured we need to redo the anti-collision
|
||||
if (!nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti))
|
||||
if (!nfc_initiator_select_tag(pnd,NM_ISO14443A_106,NULL,0,&nti))
|
||||
{
|
||||
printf("!\nError: tag was removed\n");
|
||||
return false;
|
||||
|
@ -95,7 +95,7 @@ bool write_card()
|
|||
// writes one page at a time.
|
||||
uiBlock = page / 4;
|
||||
memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData + ((page % 4) * 4), 16);
|
||||
if (!nfc_initiator_mifare_cmd(pdi, MC_WRITE, page, &mp)) bFailure = true;
|
||||
if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, page, &mp)) bFailure = true;
|
||||
}
|
||||
}
|
||||
printf("%c|\n",(bFailure)?'x':'.');
|
||||
|
@ -148,47 +148,47 @@ int main(int argc, const char* argv[])
|
|||
printf("Succesful opened the dump file\n");
|
||||
|
||||
// Try to open the NFC reader
|
||||
pdi = nfc_connect(NULL);
|
||||
if (pdi == INVALID_DEVICE_INFO)
|
||||
pnd = nfc_connect(NULL);
|
||||
if (pnd == NULL)
|
||||
{
|
||||
printf("Error connecting NFC reader\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
nfc_initiator_init(pdi);
|
||||
nfc_initiator_init(pnd);
|
||||
|
||||
// Drop the field for a while
|
||||
nfc_configure(pdi,DCO_ACTIVATE_FIELD,false);
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,false);
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
nfc_configure(pdi,DCO_INFINITE_SELECT,false);
|
||||
nfc_configure(pdi,DCO_HANDLE_CRC,true);
|
||||
nfc_configure(pdi,DCO_HANDLE_PARITY,true);
|
||||
nfc_configure(pnd,NDO_INFINITE_SELECT,false);
|
||||
nfc_configure(pnd,NDO_HANDLE_CRC,true);
|
||||
nfc_configure(pnd,NDO_HANDLE_PARITY,true);
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
nfc_configure(pdi,DCO_ACTIVATE_FIELD,true);
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,true);
|
||||
|
||||
printf("Connected to NFC reader: %s\n",pdi->acName);
|
||||
printf("Connected to NFC reader: %s\n",pnd->acName);
|
||||
|
||||
// Try to find a MIFARE Ultralight tag
|
||||
if (!nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti))
|
||||
if (!nfc_initiator_select_tag(pnd,NM_ISO14443A_106,NULL,0,&nti))
|
||||
{
|
||||
printf("Error: no tag was found\n");
|
||||
nfc_disconnect(pdi);
|
||||
nfc_disconnect(pnd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Test if we are dealing with a MIFARE compatible tag
|
||||
|
||||
if (ti.tia.abtAtqa[1] != 0x44){
|
||||
if (nti.nai.abtAtqa[1] != 0x44){
|
||||
printf("Error: tag is not a MIFARE Ultralight card\n");
|
||||
nfc_disconnect(pdi);
|
||||
nfc_disconnect(pnd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// Get the info from the current tag
|
||||
pbtUID = ti.tia.abtUid;
|
||||
pbtUID = nti.nai.abtUid;
|
||||
printf("Found MIFARE Ultralight card with uid: %08x\n", swap_endian32(pbtUID));
|
||||
|
||||
if (bReadAction)
|
||||
|
@ -218,7 +218,7 @@ int main(int argc, const char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
nfc_disconnect(pdi);
|
||||
nfc_disconnect(pnd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -29,17 +29,19 @@
|
|||
|
||||
#include <nfc.h>
|
||||
|
||||
#include "messages.h"
|
||||
#include "nfc-messages.h"
|
||||
#include "bitutils.h"
|
||||
|
||||
#define MAX_FRAME_LEN 264
|
||||
|
||||
static byte_t abtReaderRx[MAX_FRAME_LEN];
|
||||
static byte_t abtReaderRxPar[MAX_FRAME_LEN];
|
||||
static size_t szReaderRxBits;
|
||||
static byte_t abtTagRx[MAX_FRAME_LEN];
|
||||
static byte_t abtTagRxPar[MAX_FRAME_LEN];
|
||||
static size_t szTagRxBits;
|
||||
static dev_info* pdiReader;
|
||||
static dev_info* pdiTag;
|
||||
static nfc_device_t* pndReader;
|
||||
static nfc_device_t* pndTag;
|
||||
static bool quitting=false;
|
||||
|
||||
void intr_hdlr(void)
|
||||
|
@ -84,8 +86,8 @@ int main(int argc,char* argv[])
|
|||
#endif
|
||||
|
||||
// Try to open the NFC emulator device
|
||||
pdiTag = nfc_connect(NULL);
|
||||
if (pdiTag == INVALID_DEVICE_INFO)
|
||||
pndTag = nfc_connect(NULL);
|
||||
if (pndTag == NULL)
|
||||
{
|
||||
printf("Error connecting NFC emulator device\n");
|
||||
return 1;
|
||||
|
@ -96,41 +98,41 @@ int main(int argc,char* argv[])
|
|||
printf("[+] Try to break out the auto-emulation, this requires a second reader!\n");
|
||||
printf("[+] To do this, please send any command after the anti-collision\n");
|
||||
printf("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
|
||||
if (!nfc_target_init(pdiTag,abtReaderRx,&szReaderRxBits))
|
||||
if (!nfc_target_init(pndTag,abtReaderRx,&szReaderRxBits))
|
||||
{
|
||||
printf("[+] Initialization of NFC emulator failed\n");
|
||||
nfc_disconnect(pdiTag);
|
||||
nfc_disconnect(pndTag);
|
||||
return 1;
|
||||
}
|
||||
printf("[+] Configuring emulator settings\n");
|
||||
nfc_configure(pdiTag,DCO_HANDLE_CRC,false);
|
||||
nfc_configure(pdiTag,DCO_HANDLE_PARITY,false);
|
||||
nfc_configure(pdiTag,DCO_ACCEPT_INVALID_FRAMES,true);
|
||||
nfc_configure(pndTag,NDO_HANDLE_CRC,false);
|
||||
nfc_configure(pndTag,NDO_HANDLE_PARITY,false);
|
||||
nfc_configure(pndTag,NDO_ACCEPT_INVALID_FRAMES,true);
|
||||
printf("[+] Thank you, the emulated tag is initialized\n");
|
||||
|
||||
// Try to open the NFC reader
|
||||
pdiReader = INVALID_DEVICE_INFO;
|
||||
while (pdiReader == INVALID_DEVICE_INFO) pdiReader = nfc_connect(NULL);
|
||||
pndReader = NULL;
|
||||
while (pndReader == NULL) pndReader = nfc_connect(NULL);
|
||||
printf("[+] Configuring NFC reader settings\n");
|
||||
nfc_initiator_init(pdiReader);
|
||||
nfc_configure(pdiReader,DCO_HANDLE_CRC,false);
|
||||
nfc_configure(pdiReader,DCO_HANDLE_PARITY,false);
|
||||
nfc_configure(pdiReader,DCO_ACCEPT_INVALID_FRAMES,true);
|
||||
nfc_initiator_init(pndReader);
|
||||
nfc_configure(pndReader,NDO_HANDLE_CRC,false);
|
||||
nfc_configure(pndReader,NDO_HANDLE_PARITY,false);
|
||||
nfc_configure(pndReader,NDO_ACCEPT_INVALID_FRAMES,true);
|
||||
printf("[+] Done, relaying frames now!\n\n");
|
||||
|
||||
while(!quitting)
|
||||
{
|
||||
// Test if we received a frame from the reader
|
||||
if (nfc_target_receive_bits(pdiTag,abtReaderRx,&szReaderRxBits,abtReaderRxPar))
|
||||
if (nfc_target_receive_bits(pndTag,abtReaderRx,&szReaderRxBits,abtReaderRxPar))
|
||||
{
|
||||
// Drop down the field before sending a REQA command and start a new session
|
||||
if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26)
|
||||
{
|
||||
// Drop down field for a very short time (original tag will reboot)
|
||||
nfc_configure(pdiReader,DCO_ACTIVATE_FIELD,false);
|
||||
nfc_configure(pndReader,NDO_ACTIVATE_FIELD,false);
|
||||
if(!quiet_output)
|
||||
printf("\n");
|
||||
nfc_configure(pdiReader,DCO_ACTIVATE_FIELD,true);
|
||||
nfc_configure(pndReader,NDO_ACTIVATE_FIELD,true);
|
||||
}
|
||||
|
||||
// Print the reader frame to the screen
|
||||
|
@ -140,10 +142,10 @@ int main(int argc,char* argv[])
|
|||
print_hex_par(abtReaderRx,szReaderRxBits,abtReaderRxPar);
|
||||
}
|
||||
// Forward the frame to the original tag
|
||||
if (nfc_initiator_transceive_bits(pdiReader,abtReaderRx,szReaderRxBits,abtReaderRxPar,abtTagRx,&szTagRxBits,abtTagRxPar))
|
||||
if (nfc_initiator_transceive_bits(pndReader,abtReaderRx,szReaderRxBits,abtReaderRxPar,abtTagRx,&szTagRxBits,abtTagRxPar))
|
||||
{
|
||||
// Redirect the answer back to the reader
|
||||
nfc_target_send_bits(pdiTag,abtTagRx,szTagRxBits,abtTagRxPar);
|
||||
nfc_target_send_bits(pndTag,abtTagRx,szTagRxBits,abtTagRxPar);
|
||||
|
||||
// Print the tag frame to the screen
|
||||
if(!quiet_output)
|
||||
|
@ -155,6 +157,6 @@ int main(int argc,char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
nfc_disconnect(pdiTag);
|
||||
nfc_disconnect(pdiReader);
|
||||
nfc_disconnect(pndTag);
|
||||
nfc_disconnect(pndReader);
|
||||
}
|
||||
|
|
|
@ -25,17 +25,19 @@
|
|||
#include <string.h>
|
||||
#include <nfc.h>
|
||||
|
||||
#define MAX_FRAME_LEN 264
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
dev_info *pdi;
|
||||
tag_info ti;
|
||||
nfc_device_t *pnd;
|
||||
nfc_target_info_t ti;
|
||||
byte_t abtRecv[MAX_FRAME_LEN];
|
||||
size_t szRecvBits;
|
||||
byte_t send[] = "Hello World!";
|
||||
|
||||
pdi = nfc_connect(NULL);
|
||||
if (!pdi || !nfc_initiator_init(pdi)
|
||||
|| !nfc_initiator_select_dep_target(pdi, IM_PASSIVE_DEP, NULL, 0,
|
||||
pnd = nfc_connect(NULL);
|
||||
if (!pnd || !nfc_initiator_init(pnd)
|
||||
|| !nfc_initiator_select_dep_target(pnd, NM_PASSIVE_DEP, NULL, 0,
|
||||
NULL, 0, NULL, 0, &ti)) {
|
||||
printf
|
||||
("unable to connect, initialize, or select the target\n");
|
||||
|
@ -43,7 +45,7 @@ int main(int argc, const char *argv[])
|
|||
}
|
||||
|
||||
printf("Sending : %s\n", send);
|
||||
if (!nfc_initiator_transceive_dep_bytes(pdi,
|
||||
if (!nfc_initiator_transceive_dep_bytes(pnd,
|
||||
send,
|
||||
strlen((char*)send), abtRecv,
|
||||
&szRecvBits)) {
|
||||
|
@ -54,7 +56,7 @@ int main(int argc, const char *argv[])
|
|||
abtRecv[szRecvBits] = 0;
|
||||
printf("Received: %s\n", abtRecv);
|
||||
|
||||
nfc_initiator_deselect_tag(pdi);
|
||||
nfc_disconnect(pdi);
|
||||
nfc_initiator_deselect_tag(pnd);
|
||||
nfc_disconnect(pnd);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -24,19 +24,21 @@
|
|||
#include <stdio.h>
|
||||
#include <nfc.h>
|
||||
|
||||
#define MAX_FRAME_LEN 264
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
byte_t abtRecv[MAX_FRAME_LEN];
|
||||
size_t szRecvBits;
|
||||
byte_t send[] = "Hello Mars!";
|
||||
dev_info *pdi = nfc_connect(NULL);
|
||||
nfc_device_t *pnd = nfc_connect(NULL);
|
||||
|
||||
if (!pdi || !nfc_target_init(pdi, abtRecv, &szRecvBits)) {
|
||||
if (!pnd || !nfc_target_init(pnd, abtRecv, &szRecvBits)) {
|
||||
printf("unable to connect or initialize\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!nfc_target_receive_dep_bytes(pdi, abtRecv, &szRecvBits)) {
|
||||
if (!nfc_target_receive_dep_bytes(pnd, abtRecv, &szRecvBits)) {
|
||||
printf("unable to receive data\n");
|
||||
return 1;
|
||||
}
|
||||
|
@ -44,11 +46,11 @@ int main(int argc, const char *argv[])
|
|||
printf("Received: %s\n", abtRecv);
|
||||
printf("Sending : %s\n", send);
|
||||
|
||||
if (!nfc_target_send_dep_bytes(pdi, send, 11)) {
|
||||
if (!nfc_target_send_dep_bytes(pnd, send, 11)) {
|
||||
printf("unable to send data\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
nfc_disconnect(pdi);
|
||||
nfc_disconnect(pnd);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
# Library's chips
|
||||
SET(CHIPS_SOURCES chips/pn53x)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/chips)
|
||||
|
||||
# Library's buses
|
||||
SET(BUSES_SOURCES buses/uart)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/buses)
|
||||
|
@ -19,12 +23,12 @@ IF(LIBNFC_USB)
|
|||
FIND_PACKAGE(LIBUSB REQUIRED)
|
||||
ADD_DEFINITIONS("-DHAVE_LIBUSB=1")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBUSB_CFLAGS_OTHER}")
|
||||
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/pn531" "drivers/pn533")
|
||||
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/pn531_usb" "drivers/pn533_usb")
|
||||
ENDIF(LIBNFC_USB)
|
||||
|
||||
|
||||
# Library
|
||||
SET(LIBRARY_SOURCES nfc bitutils ${DRIVERS_SOURCES} ${BUSES_SOURCES})
|
||||
SET(LIBRARY_SOURCES nfc bitutils ${DRIVERS_SOURCES} ${BUSES_SOURCES} ${CHIPS_SOURCES})
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
ADD_LIBRARY(nfc SHARED ${LIBRARY_SOURCES})
|
||||
TARGET_LINK_LIBRARIES(nfc ${LIBUSB_LIBRARIES} ${PCSC_LIBRARIES})
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
SUBDIRS = buses drivers .
|
||||
SUBDIRS = chips buses drivers .
|
||||
|
||||
# set the include path found by configure
|
||||
INCLUDES= $(all_includes)
|
||||
|
||||
nfcinclude_HEADERS = nfc.h defines.h types.h buses.h drivers.h messages.h bitutils.h
|
||||
nfcinclude_HEADERS = nfc.h nfc-types.h nfc-messages.h chips.h buses.h drivers.h bitutils.h
|
||||
nfcincludedir = $(includedir)/nfc
|
||||
|
||||
lib_LTLIBRARIES = libnfc.la
|
||||
|
@ -11,6 +11,7 @@ libnfc_la_SOURCES = nfc.c bitutils.c
|
|||
libnfc_la_LDFLAGS = -no-undefined -version-info=0:0:0
|
||||
libnfc_la_CFLAGS =
|
||||
libnfc_la_LIBADD = \
|
||||
$(top_builddir)/src/lib/chips/libnfcchips.la \
|
||||
$(top_builddir)/src/lib/buses/libnfcbuses.la \
|
||||
$(top_builddir)/src/lib/drivers/libnfcdrivers.la
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "nfc-types.h"
|
||||
|
||||
byte_t oddparity(const byte_t bt);
|
||||
void oddparity_byte_ts(const byte_t* pbtData, const size_t szLen, byte_t* pbtPar);
|
||||
|
|
|
@ -21,3 +21,5 @@
|
|||
* @brief
|
||||
*/
|
||||
|
||||
#include "nfc-types.h"
|
||||
|
||||
|
|
|
@ -22,14 +22,13 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
Based on uart-code written by Teunis van Beelen available:
|
||||
Based on RS232 code written by Teunis van Beelen available:
|
||||
http://www.teuniz.net/RS-232/index.html
|
||||
*/
|
||||
|
||||
|
||||
#include "uart.h"
|
||||
|
||||
#include "messages.h"
|
||||
#include "nfc-messages.h"
|
||||
|
||||
// Test if we are dealing with unix operating systems
|
||||
#ifndef _WIN32
|
||||
|
@ -132,7 +131,7 @@ void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
|||
cfsetospeed((struct termios*)&spu->tiNew, stPortSpeed);
|
||||
if( tcsetattr(spu->fd, TCSADRAIN, &spu->tiNew) == -1)
|
||||
{
|
||||
ERR("Unable to apply new speed settings.");
|
||||
ERR("%s", "Unable to apply new speed settings.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,7 +195,7 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
|||
|
||||
// Read error
|
||||
if (res < 0) {
|
||||
DBG("RX error.");
|
||||
DBG("%s", "RX error.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -204,7 +203,7 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
|||
if (res == 0) {
|
||||
if (*pszRxLen == 0) {
|
||||
// Error, we received no data
|
||||
DBG("RX time-out, buffer empty.");
|
||||
DBG("%s", "RX time-out, buffer empty.");
|
||||
return false;
|
||||
} else {
|
||||
// We received some data, but nothing more is available
|
||||
|
@ -246,13 +245,13 @@ bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
|||
|
||||
// Write error
|
||||
if (res < 0) {
|
||||
DBG("TX error.");
|
||||
DBG("%s", "TX error.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write time-out
|
||||
if (res == 0) {
|
||||
DBG("TX time-out.");
|
||||
DBG("%s", "TX time-out.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -368,6 +367,13 @@ uint32_t uart_get_speed(const serial_port sp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool uart_cts(const serial_port sp)
|
||||
{
|
||||
char status;
|
||||
if (ioctl(((serial_port_unix*)sp)->fd,TIOCMGET,&status) < 0) return false;
|
||||
return (status & TIOCM_CTS);
|
||||
}
|
||||
|
||||
bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
ReadFile(((serial_port_windows*)sp)->hPort,pbtRx,*pszRxLen,(LPDWORD)pszRxLen,NULL);
|
||||
|
@ -381,4 +387,4 @@ bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
|||
return (dwTxLen != 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
|
|
@ -21,14 +21,15 @@
|
|||
* @brief
|
||||
*/
|
||||
|
||||
#ifndef _LIBNFC_RS232_H_
|
||||
#define _LIBNFC_RS232_H_
|
||||
#ifndef __NFC_BUS_UART_H__
|
||||
#define __NFC_BUS_UART_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "defines.h"
|
||||
#include "types.h"
|
||||
|
||||
|
||||
#include "nfc-types.h"
|
||||
|
||||
// Handle platform specific includes
|
||||
#ifndef _WIN32
|
||||
|
@ -58,6 +59,6 @@ uint32_t uart_get_speed(const serial_port sp);
|
|||
bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen);
|
||||
|
||||
#endif // _LIBNFC_RS232_H_
|
||||
#endif // __NFC_BUS_UART_H__
|
||||
|
||||
|
||||
|
|
32
src/lib/chips.h
Normal file
32
src/lib/chips.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* Public platform independent Near Field Communication (NFC) library
|
||||
*
|
||||
* Copyright (C) 2009, Roel Verdult
|
||||
*
|
||||
* This program 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 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* 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 Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*
|
||||
* @file chips.h
|
||||
* @brief NFC chips header
|
||||
*/
|
||||
|
||||
#ifndef __NFC_CHIPS_H__
|
||||
#define __NFC_CHIPS_H__
|
||||
|
||||
#include "nfc-types.h"
|
||||
|
||||
#include "chips/pn53x.h"
|
||||
|
||||
#endif // __NFC_CHIPS_H__
|
||||
|
10
src/lib/chips/Makefile.am
Normal file
10
src/lib/chips/Makefile.am
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
# set the include path found by configure
|
||||
INCLUDES= $(all_includes)
|
||||
|
||||
noinst_HEADERS = pn53x.h
|
||||
noinst_LTLIBRARIES = libnfcchips.la
|
||||
libnfcchips_la_SOURCES = pn53x.c
|
||||
libnfcchips_la_CFLAGS = -I$(top_srcdir)/src/lib
|
||||
|
||||
DISTCLEANFILES = Makefile.in
|
234
src/lib/chips/pn53x.c
Normal file
234
src/lib/chips/pn53x.c
Normal file
|
@ -0,0 +1,234 @@
|
|||
/**
|
||||
* Public platform independent Near Field Communication (NFC) library
|
||||
*
|
||||
* Copyright (C) 2009, Roel Verdult
|
||||
*
|
||||
* This program 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 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* 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 Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*
|
||||
* @file pn53x.h
|
||||
* @brief PN531, PN532 and PN533 common functions
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pn53x.h"
|
||||
|
||||
#include "bitutils.h"
|
||||
|
||||
// PN53X configuration
|
||||
const byte_t pncmd_get_firmware_version [ 2] = { 0xD4,0x02 };
|
||||
const byte_t pncmd_get_general_status [ 2] = { 0xD4,0x04 };
|
||||
const byte_t pncmd_get_register [ 4] = { 0xD4,0x06 };
|
||||
const byte_t pncmd_set_register [ 5] = { 0xD4,0x08 };
|
||||
const byte_t pncmd_set_parameters [ 3] = { 0xD4,0x12 };
|
||||
const byte_t pncmd_rf_configure [ 14] = { 0xD4,0x32 };
|
||||
|
||||
// Reader
|
||||
const byte_t pncmd_initiator_list_passive [264] = { 0xD4,0x4A };
|
||||
const byte_t pncmd_initiator_jump_for_dep [ 68] = { 0xD4,0x56 };
|
||||
const byte_t pncmd_initiator_select [ 3] = { 0xD4,0x54 };
|
||||
const byte_t pncmd_initiator_deselect [ 3] = { 0xD4,0x44,0x00 };
|
||||
const byte_t pncmd_initiator_release [ 3] = { 0xD4,0x52,0x00 };
|
||||
const byte_t pncmd_initiator_set_baud_rate [ 5] = { 0xD4,0x4E };
|
||||
const byte_t pncmd_initiator_exchange_data [265] = { 0xD4,0x40 };
|
||||
const byte_t pncmd_initiator_exchange_raw_data [266] = { 0xD4,0x42 };
|
||||
const byte_t pncmd_initiator_auto_poll [ 5] = { 0xD4,0x60 };
|
||||
|
||||
// Target
|
||||
const byte_t pncmd_target_get_data [ 2] = { 0xD4,0x86 };
|
||||
const byte_t pncmd_target_set_data [264] = { 0xD4,0x8E };
|
||||
const byte_t pncmd_target_init [ 39] = { 0xD4,0x8C };
|
||||
const byte_t pncmd_target_virtual_card [ 4] = { 0xD4,0x14 };
|
||||
const byte_t pncmd_target_receive [ 2] = { 0xD4,0x88 };
|
||||
const byte_t pncmd_target_send [264] = { 0xD4,0x90 };
|
||||
const byte_t pncmd_target_get_status [ 2] = { 0xD4,0x8A };
|
||||
|
||||
|
||||
bool pn53x_transceive(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
|
||||
// Check if receiving buffers are available, if not, replace them
|
||||
if (!pszRxLen || !pbtRx)
|
||||
{
|
||||
pbtRx = abtRx;
|
||||
pszRxLen = &szRxLen;
|
||||
}
|
||||
|
||||
*pszRxLen = MAX_FRAME_LEN;
|
||||
// Call the tranceive callback function of the current device
|
||||
if (!pnd->pdc->transceive(pnd->nds,pbtTx,szTxLen,pbtRx,pszRxLen)) return false;
|
||||
|
||||
// Make sure there was no failure reported by the PN53X chip (0x00 == OK)
|
||||
if (pbtRx[0] != 0) return false;
|
||||
|
||||
// Succesful transmission
|
||||
return true;
|
||||
}
|
||||
|
||||
byte_t pn53x_get_reg(const nfc_device_t* pnd, uint16_t ui16Reg)
|
||||
{
|
||||
uint8_t ui8Value;
|
||||
size_t szValueLen = 1;
|
||||
byte_t abtCmd[sizeof(pncmd_get_register)];
|
||||
memcpy(abtCmd,pncmd_get_register,sizeof(pncmd_get_register));
|
||||
|
||||
abtCmd[2] = ui16Reg >> 8;
|
||||
abtCmd[3] = ui16Reg & 0xff;
|
||||
// We can not use pn53x_transceive() because abtRx[0] gives no status info
|
||||
pnd->pdc->transceive(pnd->nds,abtCmd,4,&ui8Value,&szValueLen);
|
||||
return ui8Value;
|
||||
}
|
||||
|
||||
bool pn53x_set_reg(const nfc_device_t* pnd, uint16_t ui16Reg, uint8_t ui8SybmolMask, uint8_t ui8Value)
|
||||
{
|
||||
byte_t abtCmd[sizeof(pncmd_set_register)];
|
||||
memcpy(abtCmd,pncmd_set_register,sizeof(pncmd_set_register));
|
||||
|
||||
abtCmd[2] = ui16Reg >> 8;
|
||||
abtCmd[3] = ui16Reg & 0xff;
|
||||
abtCmd[4] = ui8Value | (pn53x_get_reg(pnd,ui16Reg) & (~ui8SybmolMask));
|
||||
// We can not use pn53x_transceive() because abtRx[0] gives no status info
|
||||
return pnd->pdc->transceive(pnd->nds,abtCmd,5,NULL,NULL);
|
||||
}
|
||||
|
||||
bool pn53x_set_parameters(const nfc_device_t* pnd, uint8_t ui8Value)
|
||||
{
|
||||
byte_t abtCmd[sizeof(pncmd_set_parameters)];
|
||||
memcpy(abtCmd,pncmd_set_parameters,sizeof(pncmd_set_parameters));
|
||||
|
||||
abtCmd[2] = ui8Value;
|
||||
// We can not use pn53x_transceive() because abtRx[0] gives no status info
|
||||
return pnd->pdc->transceive(pnd->nds,abtCmd,3,NULL,NULL);
|
||||
}
|
||||
|
||||
bool pn53x_set_tx_bits(const nfc_device_t* pnd, uint8_t ui8Bits)
|
||||
{
|
||||
// Test if we need to update the transmission bits register setting
|
||||
if (pnd->ui8TxBits != ui8Bits)
|
||||
{
|
||||
// Set the amount of transmission bits in the PN53X chip register
|
||||
if (!pn53x_set_reg(pnd,REG_CIU_BIT_FRAMING,SYMBOL_TX_LAST_BITS,ui8Bits)) return false;
|
||||
|
||||
// Store the new setting
|
||||
((nfc_device_t*)pnd)->ui8TxBits = ui8Bits;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pn53x_wrap_frame(const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtFrame, size_t* pszFrameBits)
|
||||
{
|
||||
byte_t btFrame;
|
||||
byte_t btData;
|
||||
uint32_t uiBitPos;
|
||||
uint32_t uiDataPos = 0;
|
||||
size_t szBitsLeft = szTxBits;
|
||||
|
||||
// Make sure we should frame at least something
|
||||
if (szBitsLeft == 0) return false;
|
||||
|
||||
// Handle a short response (1byte) as a special case
|
||||
if (szBitsLeft < 9)
|
||||
{
|
||||
*pbtFrame = *pbtTx;
|
||||
*pszFrameBits = szTxBits;
|
||||
return true;
|
||||
}
|
||||
|
||||
// We start by calculating the frame length in bits
|
||||
*pszFrameBits = szTxBits + (szTxBits/8);
|
||||
|
||||
// Parse the data bytes and add the parity bits
|
||||
// This is really a sensitive process, mirror the frame bytes and append parity bits
|
||||
// buffer = mirror(frame-byte) + parity + mirror(frame-byte) + parity + ...
|
||||
// split "buffer" up in segments of 8 bits again and mirror them
|
||||
// air-bytes = mirror(buffer-byte) + mirror(buffer-byte) + mirror(buffer-byte) + ..
|
||||
while(true)
|
||||
{
|
||||
// Reset the temporary frame byte;
|
||||
btFrame = 0;
|
||||
|
||||
for (uiBitPos=0; uiBitPos<8; uiBitPos++)
|
||||
{
|
||||
// Copy as much data that fits in the frame byte
|
||||
btData = mirror(pbtTx[uiDataPos]);
|
||||
btFrame |= (btData >> uiBitPos);
|
||||
// Save this frame byte
|
||||
*pbtFrame = mirror(btFrame);
|
||||
// Set the remaining bits of the date in the new frame byte and append the parity bit
|
||||
btFrame = (btData << (8-uiBitPos));
|
||||
btFrame |= ((pbtTxPar[uiDataPos] & 0x01) << (7-uiBitPos));
|
||||
// Backup the frame bits we have so far
|
||||
pbtFrame++;
|
||||
*pbtFrame = mirror(btFrame);
|
||||
// Increase the data (without parity bit) position
|
||||
uiDataPos++;
|
||||
// Test if we are done
|
||||
if (szBitsLeft < 9) return true;
|
||||
szBitsLeft -= 8;
|
||||
}
|
||||
// Every 8 data bytes we lose one frame byte to the parities
|
||||
pbtFrame++;
|
||||
}
|
||||
}
|
||||
|
||||
bool pn53x_unwrap_frame(const byte_t* pbtFrame, const size_t szFrameBits, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
|
||||
{
|
||||
byte_t btFrame;
|
||||
byte_t btData;
|
||||
uint8_t uiBitPos;
|
||||
uint32_t uiDataPos = 0;
|
||||
byte_t* pbtFramePos = (byte_t*) pbtFrame;
|
||||
size_t szBitsLeft = szFrameBits;
|
||||
|
||||
// Make sure we should frame at least something
|
||||
if (szBitsLeft == 0) return false;
|
||||
|
||||
// Handle a short response (1byte) as a special case
|
||||
if (szBitsLeft < 9)
|
||||
{
|
||||
*pbtRx = *pbtFrame;
|
||||
*pszRxBits = szFrameBits;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calculate the data length in bits
|
||||
*pszRxBits = szFrameBits - (szFrameBits/9);
|
||||
|
||||
// Parse the frame bytes, remove the parity bits and store them in the parity array
|
||||
// This process is the reverse of WrapFrame(), look there for more info
|
||||
while(true)
|
||||
{
|
||||
for (uiBitPos=0; uiBitPos<8; uiBitPos++)
|
||||
{
|
||||
btFrame = mirror(pbtFramePos[uiDataPos]);
|
||||
btData = (btFrame << uiBitPos);
|
||||
btFrame = mirror(pbtFramePos[uiDataPos+1]);
|
||||
btData |= (btFrame >> (8-uiBitPos));
|
||||
pbtRx[uiDataPos] = mirror(btData);
|
||||
if(pbtRxPar != NULL) pbtRxPar[uiDataPos] = ((btFrame >> (7-uiBitPos)) & 0x01);
|
||||
// Increase the data (without parity bit) position
|
||||
uiDataPos++;
|
||||
// Test if we are done
|
||||
if (szBitsLeft < 9) return true;
|
||||
szBitsLeft -= 9;
|
||||
}
|
||||
// Every 8 data bytes we lose one frame byte to the parities
|
||||
pbtFramePos++;
|
||||
}
|
||||
}
|
||||
|
80
src/lib/chips/pn53x.h
Normal file
80
src/lib/chips/pn53x.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* Public platform independent Near Field Communication (NFC) library
|
||||
*
|
||||
* Copyright (C) 2009, Roel Verdult
|
||||
*
|
||||
* This program 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 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* 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 Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*
|
||||
* @file pn53x.h
|
||||
* @brief PN531, PN532 and PN533 common functions
|
||||
*/
|
||||
|
||||
#ifndef __NFC_CHIPS_PN53X_H__
|
||||
#define __NFC_CHIPS_PN53X_H__
|
||||
|
||||
#include "nfc-types.h"
|
||||
|
||||
#define MAX_FRAME_LEN 264
|
||||
|
||||
// Registers and symbols masks used to covers parts within a register
|
||||
#define REG_CIU_TX_MODE 0x6302
|
||||
#define SYMBOL_TX_CRC_ENABLE 0x80
|
||||
#define REG_CIU_RX_MODE 0x6303
|
||||
#define SYMBOL_RX_CRC_ENABLE 0x80
|
||||
#define SYMBOL_RX_NO_ERROR 0x08
|
||||
#define SYMBOL_RX_MULTIPLE 0x04
|
||||
#define REG_CIU_TX_AUTO 0x6305
|
||||
#define SYMBOL_FORCE_100_ASK 0x40
|
||||
#define SYMBOL_AUTO_WAKE_UP 0x20
|
||||
#define SYMBOL_INITIAL_RF_ON 0x04
|
||||
#define REG_CIU_MANUAL_RCV 0x630D
|
||||
#define SYMBOL_PARITY_DISABLE 0x10
|
||||
#define REG_CIU_STATUS2 0x6338
|
||||
#define SYMBOL_MF_CRYPTO1_ON 0x08
|
||||
#define REG_CIU_CONTROL 0x633C
|
||||
#define SYMBOL_INITIATOR 0x10
|
||||
#define SYMBOL_RX_LAST_BITS 0x07
|
||||
#define REG_CIU_BIT_FRAMING 0x633D
|
||||
#define SYMBOL_TX_LAST_BITS 0x07
|
||||
|
||||
// Internal parameters flags
|
||||
#define PARAM_NONE 0x00
|
||||
#define PARAM_NAD_USED 0x01
|
||||
#define PARAM_DID_USED 0x02
|
||||
#define PARAM_AUTO_ATR_RES 0x04
|
||||
#define PARAM_AUTO_RATS 0x10
|
||||
#define PARAM_14443_4_PICC 0x20
|
||||
#define PARAM_NO_AMBLE 0x40
|
||||
|
||||
// Radio Field Configure Items // Configuration Data length
|
||||
#define RFCI_FIELD 0x01 // 1
|
||||
#define RFCI_TIMING 0x02 // 3
|
||||
#define RFCI_RETRY_DATA 0x04 // 1
|
||||
#define RFCI_RETRY_SELECT 0x05 // 3
|
||||
#define RFCI_ANALOG_TYPE_A_106 0x0A // 11
|
||||
#define RFCI_ANALOG_TYPE_A_212_424 0x0B // 8
|
||||
#define RFCI_ANALOG_TYPE_B 0x0C // 3
|
||||
#define RFCI_ANALOG_TYPE_14443_4 0x0D // 9
|
||||
|
||||
bool pn53x_transceive(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
byte_t pn53x_get_reg(const nfc_device_t* pnd, uint16_t ui16Reg);
|
||||
bool pn53x_set_reg(const nfc_device_t* pnd, uint16_t ui16Reg, uint8_t ui8SybmolMask, uint8_t ui8Value);
|
||||
bool pn53x_set_parameters(const nfc_device_t* pnd, uint8_t ui8Value);
|
||||
bool pn53x_set_tx_bits(const nfc_device_t* pnd, uint8_t ui8Bits);
|
||||
bool pn53x_wrap_frame(const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtFrame, size_t* pszFrameBits);
|
||||
bool pn53x_unwrap_frame(const byte_t* pbtFrame, const size_t szFrameBits, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar);
|
||||
|
||||
#endif // __NFC_CHIPS_PN53X_H__
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/**
|
||||
* Public platform independent Near Field Communication (NFC) library
|
||||
*
|
||||
* Copyright (C) 2009, Roel Verdult
|
||||
*
|
||||
* This program 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 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* 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 Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*
|
||||
* @file defines.h
|
||||
* @brief
|
||||
*/
|
||||
|
||||
#ifndef _LIBNFC_DEFINES_H_
|
||||
#define _LIBNFC_DEFINES_H_
|
||||
|
||||
//#define DEBUG /* DEBUG flag can also be enabled using ./configure --enable-debug */
|
||||
|
||||
typedef void* dev_spec; // Device connection specification
|
||||
#define INVALID_DEVICE_INFO 0
|
||||
#define MAX_FRAME_LEN 264
|
||||
#define DEVICE_NAME_LENGTH 256
|
||||
#define MAX_DEVICES 16
|
||||
|
||||
#if defined __cplusplus
|
||||
#define LIBNFC_EXTERN_C extern "C"
|
||||
#else
|
||||
#define LIBNFC_EXTERN_C
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef nfc_EXPORTS
|
||||
#define LIBNFC_DECLSPEC __declspec( dllexport )
|
||||
#else
|
||||
#define LIBNFC_DECLSPEC __declspec( dllimport )
|
||||
#endif
|
||||
#else
|
||||
#define LIBNFC_DECLSPEC
|
||||
#endif
|
||||
|
||||
#define LIBNFC_EXPORT LIBNFC_EXTERN_C LIBNFC_DECLSPEC
|
||||
|
||||
//#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
//#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#define INNER_XOR8(n) {n ^= (n >> 4); n ^= (n >> 2); n ^= (n >> 1); n &= 0x01; }
|
||||
#define INNER_XOR32(n) {n ^= (n >> 16); n ^= (n >> 8); INNER_XOR8(n); }
|
||||
#define INNER_XOR64(n) {n ^= (n >> 32); INNER_XOR32(n); }
|
||||
|
||||
#endif // _LIBNFC_DEFINES_H_
|
|
@ -17,37 +17,42 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*
|
||||
* @file devices.h
|
||||
* @file drivers.h
|
||||
* @brief
|
||||
*/
|
||||
|
||||
#ifndef _LIBNFC_DEVICES_H_
|
||||
#define _LIBNFC_DEVICES_H_
|
||||
#ifndef __NFC_DRIVERS_H__
|
||||
#define __NFC_DRIVERS_H__
|
||||
|
||||
#include "nfc-types.h"
|
||||
|
||||
#include "defines.h"
|
||||
#include "types.h"
|
||||
#ifdef HAVE_PCSC_LITE
|
||||
#include "drivers/acr122.h"
|
||||
#endif /* HAVE_PCSC_LITE */
|
||||
|
||||
#ifdef HAVE_LIBUSB
|
||||
#include "drivers/pn531.h"
|
||||
#include "drivers/pn533.h"
|
||||
#include "drivers/pn531_usb.h"
|
||||
#include "drivers/pn533_usb.h"
|
||||
#endif /* HAVE_LIBUSB */
|
||||
|
||||
#include "drivers/arygon.h"
|
||||
#include "drivers/pn532_uart.h"
|
||||
|
||||
#define DRIVERS_MAX_DEVICES 16
|
||||
#define MAX_FRAME_LEN 264
|
||||
|
||||
const static struct driver_callbacks drivers_callbacks_list[] = {
|
||||
// Driver Name Connect Transceive Disconnect
|
||||
// Driver Name Pick Device List Devices Connect Transceive Disconnect
|
||||
#ifdef HAVE_PCSC_LITE
|
||||
{ "ACR122", acr122_connect, acr122_transceive, acr122_disconnect },
|
||||
{ ACR122_DRIVER_NAME, acr122_pick_device, acr122_list_devices, acr122_connect, acr122_transceive, acr122_disconnect },
|
||||
#endif /* HAVE_PCSC_LITE */
|
||||
#ifdef HAVE_LIBUSB
|
||||
{ "PN531USB", pn531_connect, pn531_transceive, pn531_disconnect },
|
||||
{ "PN533USB", pn533_connect, pn533_transceive, pn533_disconnect },
|
||||
{ PN531_USB_DRIVER_NAME, NULL, NULL, pn531_usb_connect, pn531_usb_transceive, pn531_usb_disconnect },
|
||||
{ PN533_USB_DRIVER_NAME, NULL, NULL, pn533_usb_connect, pn533_usb_transceive, pn533_usb_disconnect },
|
||||
#endif /* HAVE_LIBUSB */
|
||||
{ "PN532_UART", pn532_uart_connect, pn532_uart_transceive, pn532_uart_disconnect },
|
||||
{ "ARYGON", arygon_connect, arygon_transceive, arygon_disconnect }
|
||||
{ PN532_UART_DRIVER_NAME, NULL, NULL, pn532_uart_connect, pn532_uart_transceive, pn532_uart_disconnect },
|
||||
{ ARYGON_DRIVER_NAME, NULL, NULL, arygon_connect, arygon_transceive, arygon_disconnect }
|
||||
};
|
||||
|
||||
#endif // _LIBNFC_DEVICES_H_
|
||||
#endif // __NFC_DRIVERS_H__
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ if PCSC_LITE_ENABLED
|
|||
endif
|
||||
|
||||
if LIBUSB_ENABLED
|
||||
noinst_HEADERS += pn531.h pn533.h
|
||||
noinst_HEADERS += pn531_usb.h pn533_usb.h
|
||||
libnfcdrivers_la_CFLAGS += @LIBUSB_CFLAGS@ -DHAVE_LIBUSB
|
||||
libnfcdrivers_la_SOURCES += pn531.c pn533.c
|
||||
libnfcdrivers_la_SOURCES += pn531_usb.c pn533_usb.c
|
||||
libnfcdrivers_la_LIBADD += @LIBUSB_LIBS@
|
||||
endif
|
||||
|
||||
|
|
|
@ -21,20 +21,24 @@
|
|||
* @brief
|
||||
*/
|
||||
|
||||
#include "acr122.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "acr122.h"
|
||||
#include "../drivers.h"
|
||||
#include "../bitutils.h"
|
||||
|
||||
// Bus
|
||||
#include <winscard.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <wintypes.h>
|
||||
#endif
|
||||
|
||||
#include "defines.h"
|
||||
#include "messages.h"
|
||||
|
||||
#include "nfc-messages.h"
|
||||
|
||||
// WINDOWS: #define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE SCARD_CTL_CODE(3500)
|
||||
#define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE (((0x31) << 16) | ((3500) << 2))
|
||||
|
@ -51,134 +55,201 @@
|
|||
#define ACR122_COMMAND_LEN 266
|
||||
#define ACR122_RESPONSE_LEN 268
|
||||
|
||||
const char *supported_devices[] = {
|
||||
"ACS ACR122U PICC Interface",
|
||||
"ACS ACR 38U-CCID",
|
||||
NULL
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
SCARDCONTEXT hCtx;
|
||||
SCARDHANDLE hCard;
|
||||
SCARD_IO_REQUEST ioCard;
|
||||
} dev_spec_acr122;
|
||||
} acr122_spec_t;
|
||||
|
||||
dev_info* acr122_connect(const nfc_device_desc_t* pndd)
|
||||
static SCARDCONTEXT _SCardContext;
|
||||
static int _iSCardContextRefCount = 0;
|
||||
|
||||
SCARDCONTEXT*
|
||||
acr122_get_scardcontext(void)
|
||||
{
|
||||
char* pacReaders[MAX_DEVICES];
|
||||
char acList[256+64*MAX_DEVICES];
|
||||
size_t szListLen = sizeof(acList);
|
||||
size_t szPos;
|
||||
uint32_t uiReaderCount;
|
||||
uint32_t uiReader;
|
||||
uint32_t uiDevIndex;
|
||||
dev_info* pdi;
|
||||
dev_spec_acr122* pdsa;
|
||||
dev_spec_acr122 dsa;
|
||||
char* pcFirmware;
|
||||
if ( _iSCardContextRefCount == 0 )
|
||||
{
|
||||
if (SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&_SCardContext) != SCARD_S_SUCCESS) return NULL;
|
||||
}
|
||||
_iSCardContextRefCount++;
|
||||
|
||||
return &_SCardContext;
|
||||
}
|
||||
|
||||
void
|
||||
acr122_free_scardcontext(void)
|
||||
{
|
||||
if (_iSCardContextRefCount)
|
||||
{
|
||||
_iSCardContextRefCount--;
|
||||
if (!_iSCardContextRefCount)
|
||||
{
|
||||
SCardReleaseContext(_SCardContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nfc_device_desc_t *
|
||||
acr122_pick_device (void)
|
||||
{
|
||||
nfc_device_desc_t *pndd;
|
||||
|
||||
if ((pndd = malloc (sizeof (*pndd)))) {
|
||||
size_t szN;
|
||||
|
||||
if (!acr122_list_devices (pndd, 1, &szN)) {
|
||||
ERR("%s", "acr122_list_devices failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (szN == 0) {
|
||||
ERR("%s", "No device found");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pndd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn bool acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
* @brief List connected devices
|
||||
*
|
||||
* Probe PCSC to find NFC capable hardware.
|
||||
*
|
||||
* @param pnddDevices Array of nfc_device_desc_t previously allocated by the caller.
|
||||
* @param szDevices size of the pnddDevices array.
|
||||
* @param pszDeviceFound number of devices found.
|
||||
* @return true if succeeded, false otherwise.
|
||||
*/
|
||||
bool
|
||||
acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
{
|
||||
size_t szPos = 0;
|
||||
char acDeviceNames[256+64*DRIVERS_MAX_DEVICES];
|
||||
size_t szDeviceNamesLen = sizeof(acDeviceNames);
|
||||
acr122_spec_t as;
|
||||
uint32_t uiBusIndex = 0;
|
||||
char *pcFirmware;
|
||||
SCARDCONTEXT *pscc;
|
||||
|
||||
// Clear the reader list
|
||||
memset(acList,0x00,szListLen);
|
||||
memset(acDeviceNames, '\0', szDeviceNamesLen);
|
||||
|
||||
*pszDeviceFound = 0;
|
||||
|
||||
// Test if context succeeded
|
||||
if (SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&(dsa.hCtx)) != SCARD_S_SUCCESS) return INVALID_DEVICE_INFO;
|
||||
if (!(pscc = acr122_get_scardcontext ())) return false;
|
||||
|
||||
// Retrieve the string array of all available pcsc readers
|
||||
if (SCardListReaders(dsa.hCtx,NULL,acList,(void*)&szListLen) != SCARD_S_SUCCESS) return INVALID_DEVICE_INFO;
|
||||
if (SCardListReaders(*pscc,NULL,acDeviceNames,(void*)&szDeviceNamesLen) != SCARD_S_SUCCESS) return false;
|
||||
|
||||
DBG("PCSC reports following device(s):");
|
||||
DBG("- %s",acList);
|
||||
DBG("%s", "PCSC reports following device(s):");
|
||||
|
||||
pacReaders[0] = acList;
|
||||
uiReaderCount = 1;
|
||||
for (szPos=0; szPos<szListLen; szPos++)
|
||||
{
|
||||
// Make sure don't break out of our reader array
|
||||
if (uiReaderCount == MAX_DEVICES) break;
|
||||
while ((acDeviceNames[szPos] != '\0') && ((*pszDeviceFound) < szDevices)) {
|
||||
uiBusIndex++;
|
||||
|
||||
// Test if there is a next reader available
|
||||
if (acList[szPos] == 0x00)
|
||||
{
|
||||
// Test if we are at the end of the list
|
||||
if (acList[szPos+1] == 0x00)
|
||||
{
|
||||
break;
|
||||
}
|
||||
// Store the position of the next reader and search for more readers
|
||||
pacReaders[uiReaderCount] = acList+szPos+1;
|
||||
uiReaderCount++;
|
||||
DBG("- %s (pos=%d)", acDeviceNames + szPos, szPos);
|
||||
|
||||
DBG("- %s",acList+szPos+1);
|
||||
bool bSupported = false;
|
||||
for (int i = 0; supported_devices[i]; i++) {
|
||||
int l = strlen(supported_devices[i]);
|
||||
bSupported = 0 == strncmp(supported_devices[i], acDeviceNames + szPos, l);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the device index we are seaching for
|
||||
if( pndd == NULL ) {
|
||||
uiDevIndex = 0;
|
||||
} else {
|
||||
uiDevIndex = pndd->uiIndex;
|
||||
}
|
||||
|
||||
// Iterate through all readers and try to find the ACR122 on requested index
|
||||
for (uiReader=0; uiReader<uiReaderCount; uiReader++)
|
||||
{
|
||||
// Test if we were able to connect to the "emulator" card
|
||||
if (SCardConnect(dsa.hCtx,pacReaders[uiReader],SCARD_SHARE_EXCLUSIVE,SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,&(dsa.hCard),(void*)&(dsa.ioCard.dwProtocol)) != SCARD_S_SUCCESS)
|
||||
if (bSupported)
|
||||
{
|
||||
// Connect to ACR122 firmware version >2.0
|
||||
if (SCardConnect(dsa.hCtx,pacReaders[uiReader],SCARD_SHARE_DIRECT,0,&(dsa.hCard),(void*)&(dsa.ioCard.dwProtocol)) != SCARD_S_SUCCESS)
|
||||
{
|
||||
// We can not connect to this device, we will just ignore it
|
||||
continue;
|
||||
}
|
||||
// Supported ACR122 device found
|
||||
strncpy(pnddDevices[*pszDeviceFound].acDevice, acDeviceNames + szPos, BUFSIZ - 1);
|
||||
pnddDevices[*pszDeviceFound].acDevice[BUFSIZ - 1] = '\0';
|
||||
pnddDevices[*pszDeviceFound].pcDriver = ACR122_DRIVER_NAME;
|
||||
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
|
||||
(*pszDeviceFound)++;
|
||||
}
|
||||
// Configure I/O settings for card communication
|
||||
dsa.ioCard.cbPciLength = sizeof(SCARD_IO_REQUEST);
|
||||
|
||||
// Retrieve the current firmware version
|
||||
pcFirmware = acr122_firmware((dev_info*)&dsa);
|
||||
if (strstr(pcFirmware,FIRMWARE_TEXT) != NULL)
|
||||
else
|
||||
{
|
||||
// We found a occurence, test if it has the right index
|
||||
if (uiDevIndex != 0)
|
||||
{
|
||||
// Let's look for the next reader
|
||||
uiDevIndex--;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Allocate memory and store the device specification
|
||||
pdsa = malloc(sizeof(dev_spec_acr122));
|
||||
*pdsa = dsa;
|
||||
|
||||
// Done, we found the reader we are looking for
|
||||
pdi = malloc(sizeof(dev_info));
|
||||
strcpy(pdi->acName,pcFirmware);
|
||||
pdi->ct = CT_PN532;
|
||||
pdi->ds = (dev_spec)pdsa;
|
||||
pdi->bActive = true;
|
||||
pdi->bCrc = true;
|
||||
pdi->bPar = true;
|
||||
pdi->ui8TxBits = 0;
|
||||
return pdi;
|
||||
DBG("%s", "Firmware version mismatch");
|
||||
}
|
||||
}
|
||||
SCardDisconnect(as.hCard,SCARD_LEAVE_CARD);
|
||||
|
||||
// Too bad, the reader could not be located;
|
||||
return INVALID_DEVICE_INFO;
|
||||
// Find next device name position
|
||||
while (acDeviceNames[szPos++] != '\0');
|
||||
}
|
||||
acr122_free_scardcontext ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void acr122_disconnect(dev_info* pdi)
|
||||
nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd)
|
||||
{
|
||||
dev_spec_acr122* pdsa = (dev_spec_acr122*)pdi->ds;
|
||||
SCardDisconnect(pdsa->hCard,SCARD_LEAVE_CARD);
|
||||
SCardReleaseContext(pdsa->hCtx);
|
||||
free(pdsa);
|
||||
free(pdi);
|
||||
nfc_device_t* pnd = NULL;
|
||||
acr122_spec_t as;
|
||||
acr122_spec_t* pas;
|
||||
char* pcFirmware;
|
||||
|
||||
SCARDCONTEXT *pscc;
|
||||
|
||||
// Test if context succeeded
|
||||
if (!(pscc = acr122_get_scardcontext ())) return NULL;
|
||||
// Test if we were able to connect to the "emulator" card
|
||||
if (SCardConnect(*pscc,pndd->acDevice,SCARD_SHARE_EXCLUSIVE,SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,&(as.hCard),(void*)&(as.ioCard.dwProtocol)) != SCARD_S_SUCCESS)
|
||||
{
|
||||
// Connect to ACR122 firmware version >2.0
|
||||
if (SCardConnect(*pscc,pndd->acDevice,SCARD_SHARE_DIRECT,0,&(as.hCard),(void*)&(as.ioCard.dwProtocol)) != SCARD_S_SUCCESS)
|
||||
{
|
||||
// We can not connect to this device.
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// Configure I/O settings for card communication
|
||||
as.ioCard.cbPciLength = sizeof(SCARD_IO_REQUEST);
|
||||
|
||||
// Retrieve the current firmware version
|
||||
pcFirmware = acr122_firmware((nfc_device_t*)&as);
|
||||
if (strstr(pcFirmware,FIRMWARE_TEXT) != NULL)
|
||||
{
|
||||
// Allocate memory and store the device specification
|
||||
pas = malloc(sizeof(acr122_spec_t));
|
||||
*pas = as;
|
||||
|
||||
// Done, we found the reader we are looking for
|
||||
pnd = malloc(sizeof(nfc_device_t));
|
||||
strncpy(pnd->acName,pcFirmware, DEVICE_NAME_LENGTH - 1);
|
||||
pnd->acName[DEVICE_NAME_LENGTH - 1] = '\0';
|
||||
pnd->nc = NC_PN532;
|
||||
pnd->nds = (nfc_device_spec_t)pas;
|
||||
pnd->bActive = true;
|
||||
pnd->bCrc = true;
|
||||
pnd->bPar = true;
|
||||
pnd->ui8TxBits = 0;
|
||||
return pnd;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool acr122_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
void acr122_disconnect(nfc_device_t* pnd)
|
||||
{
|
||||
acr122_spec_t* pas = (acr122_spec_t*)pnd->nds;
|
||||
SCardDisconnect(pas->hCard,SCARD_LEAVE_CARD);
|
||||
acr122_free_scardcontext ();
|
||||
free(pas);
|
||||
free(pnd);
|
||||
}
|
||||
|
||||
bool acr122_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
byte_t abtRxCmd[5] = { 0xFF,0xC0,0x00,0x00 };
|
||||
size_t szRxCmdLen = sizeof(abtRxCmd);
|
||||
byte_t abtRxBuf[ACR122_RESPONSE_LEN];
|
||||
size_t szRxBufLen;
|
||||
byte_t abtTxBuf[ACR122_WRAP_LEN+ACR122_COMMAND_LEN] = { 0xFF, 0x00, 0x00, 0x00 };
|
||||
dev_spec_acr122* pdsa = (dev_spec_acr122*)ds;
|
||||
acr122_spec_t* pas = (acr122_spec_t*)nds;
|
||||
|
||||
// Make sure the command does not overflow the send buffer
|
||||
if (szTxLen > ACR122_COMMAND_LEN) return false;
|
||||
|
@ -194,14 +265,14 @@ bool acr122_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTx
|
|||
print_hex(abtTxBuf,szTxLen+5);
|
||||
#endif
|
||||
|
||||
if (pdsa->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
|
||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
|
||||
{
|
||||
if (SCardControl(pdsa->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtTxBuf,szTxLen+5,abtRxBuf,szRxBufLen,(void*)&szRxBufLen) != SCARD_S_SUCCESS) return false;
|
||||
if (SCardControl(pas->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtTxBuf,szTxLen+5,abtRxBuf,szRxBufLen,(void*)&szRxBufLen) != SCARD_S_SUCCESS) return false;
|
||||
} else {
|
||||
if (SCardTransmit(pdsa->hCard,&(pdsa->ioCard),abtTxBuf,szTxLen+5,NULL,abtRxBuf,(void*)&szRxBufLen) != SCARD_S_SUCCESS) return false;
|
||||
if (SCardTransmit(pas->hCard,&(pas->ioCard),abtTxBuf,szTxLen+5,NULL,abtRxBuf,(void*)&szRxBufLen) != SCARD_S_SUCCESS) return false;
|
||||
}
|
||||
|
||||
if (pdsa->ioCard.dwProtocol == SCARD_PROTOCOL_T0)
|
||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_T0)
|
||||
{
|
||||
// Make sure we received the byte-count we expected
|
||||
if (szRxBufLen != 2) return false;
|
||||
|
@ -212,7 +283,7 @@ bool acr122_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTx
|
|||
// Retrieve the response bytes
|
||||
abtRxCmd[4] = abtRxBuf[1];
|
||||
szRxBufLen = sizeof(abtRxBuf);
|
||||
if (SCardTransmit(pdsa->hCard,&(pdsa->ioCard),abtRxCmd,szRxCmdLen,NULL,abtRxBuf,(void*)&szRxBufLen) != SCARD_S_SUCCESS) return false;
|
||||
if (SCardTransmit(pas->hCard,&(pas->ioCard),abtRxCmd,szRxCmdLen,NULL,abtRxBuf,(void*)&szRxBufLen) != SCARD_S_SUCCESS) return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -233,20 +304,20 @@ bool acr122_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTx
|
|||
return true;
|
||||
}
|
||||
|
||||
char* acr122_firmware(const dev_spec ds)
|
||||
char* acr122_firmware(const nfc_device_spec_t nds)
|
||||
{
|
||||
byte_t abtGetFw[5] = { 0xFF,0x00,0x48,0x00,0x00 };
|
||||
uint32_t uiResult;
|
||||
|
||||
dev_spec_acr122* pdsa = (dev_spec_acr122*)ds;
|
||||
acr122_spec_t* pas = (acr122_spec_t*)nds;
|
||||
static char abtFw[11];
|
||||
size_t szFwLen = sizeof(abtFw);
|
||||
memset(abtFw,0x00,szFwLen);
|
||||
if (pdsa->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
|
||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
|
||||
{
|
||||
uiResult = SCardControl(pdsa->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtGetFw,sizeof(abtGetFw),abtFw,szFwLen,(void*)&szFwLen);
|
||||
uiResult = SCardControl(pas->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtGetFw,sizeof(abtGetFw),abtFw,szFwLen,(void*)&szFwLen);
|
||||
} else {
|
||||
uiResult = SCardTransmit(pdsa->hCard,&(pdsa->ioCard),abtGetFw,sizeof(abtGetFw),NULL,(byte_t*)abtFw,(void*)&szFwLen);
|
||||
uiResult = SCardTransmit(pas->hCard,&(pas->ioCard),abtGetFw,sizeof(abtGetFw),NULL,(byte_t*)abtFw,(void*)&szFwLen);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -259,17 +330,17 @@ char* acr122_firmware(const dev_spec ds)
|
|||
return abtFw;
|
||||
}
|
||||
|
||||
bool acr122_led_red(const dev_spec ds, bool bOn)
|
||||
bool acr122_led_red(const nfc_device_spec_t nds, bool bOn)
|
||||
{
|
||||
byte_t abtLed[9] = { 0xFF,0x00,0x40,0x05,0x04,0x00,0x00,0x00,0x00 };
|
||||
dev_spec_acr122* pdsa = (dev_spec_acr122*)ds;
|
||||
acr122_spec_t* pas = (acr122_spec_t*)nds;
|
||||
byte_t abtBuf[2];
|
||||
size_t szBufLen = sizeof(abtBuf);
|
||||
if (pdsa->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
|
||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
|
||||
{
|
||||
return (SCardControl(pdsa->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtLed,sizeof(abtLed),abtBuf,szBufLen,(void*)&szBufLen) == SCARD_S_SUCCESS);
|
||||
return (SCardControl(pas->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtLed,sizeof(abtLed),abtBuf,szBufLen,(void*)&szBufLen) == SCARD_S_SUCCESS);
|
||||
} else {
|
||||
return (SCardTransmit(pdsa->hCard,&(pdsa->ioCard),abtLed,sizeof(abtLed),NULL,(byte_t*)abtBuf,(void*)&szBufLen) == SCARD_S_SUCCESS);
|
||||
return (SCardTransmit(pas->hCard,&(pas->ioCard),abtLed,sizeof(abtLed),NULL,(byte_t*)abtBuf,(void*)&szBufLen) == SCARD_S_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,25 +21,30 @@
|
|||
* @brief
|
||||
*/
|
||||
|
||||
#ifndef _LIBNFC_DEV_ACR122_H_
|
||||
#define _LIBNFC_DEV_ACR122_H_
|
||||
#ifndef __NFC_DRIVER_ACR122_H__
|
||||
#define __NFC_DRIVER_ACR122_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "types.h"
|
||||
|
||||
#include "nfc-types.h"
|
||||
|
||||
#define ACR122_DRIVER_NAME "ACR122"
|
||||
|
||||
nfc_device_desc_t* acr122_pick_device(void);
|
||||
bool acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
|
||||
// Functions used by developer to handle connection to this device
|
||||
dev_info* acr122_connect(const nfc_device_desc_t* pndd);
|
||||
void acr122_disconnect(dev_info* pdi);
|
||||
nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd);
|
||||
void acr122_disconnect(nfc_device_t* pnd);
|
||||
|
||||
// Callback function used by libnfc to transmit commands to the PN53X chip
|
||||
bool acr122_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool acr122_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
||||
// Various additional features this device supports
|
||||
char* acr122_firmware(const dev_spec ds);
|
||||
bool acr122_led_red(const dev_spec ds, bool bOn);
|
||||
char* acr122_firmware(const nfc_device_spec_t nds);
|
||||
bool acr122_led_red(const nfc_device_spec_t nds, bool bOn);
|
||||
|
||||
#endif // _LIBNFC_DEV_ACR122_H_
|
||||
#endif // ! __NFC_DRIVER_ACR122_H__
|
||||
|
||||
|
|
|
@ -20,11 +20,17 @@
|
|||
* @file arygon.c
|
||||
* @brief
|
||||
*/
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
|
||||
#include "arygon.h"
|
||||
|
||||
#include "nfc-messages.h"
|
||||
|
||||
#include "../drivers.h"
|
||||
#include "../bitutils.h"
|
||||
// Bus
|
||||
#include "uart.h"
|
||||
#include "messages.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SERIAL_STRING "COM"
|
||||
|
@ -72,21 +78,21 @@
|
|||
* @note ARYGON-APDB2UA33 (PN532 + ARYGON µC): 9600,n,8,1
|
||||
*/
|
||||
|
||||
dev_info* arygon_connect(const nfc_device_desc_t* pndd)
|
||||
nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd)
|
||||
{
|
||||
uint32_t uiDevNr;
|
||||
serial_port sp;
|
||||
char acConnect[BUFFER_LENGTH];
|
||||
dev_info* pdi = INVALID_DEVICE_INFO;
|
||||
nfc_device_t* pnd = NULL;
|
||||
|
||||
if( pndd == NULL ) {
|
||||
#ifdef DISABLE_SERIAL_AUTOPROBE
|
||||
INFO("Sorry, serial auto-probing have been disabled at compile time.");
|
||||
return INVALID_DEVICE_INFO;
|
||||
return NULL;
|
||||
#else
|
||||
DBG("Trying to find ARYGON device on serial port: %s# at %d bauds.",SERIAL_STRING, SERIAL_DEFAULT_PORT_SPEED);
|
||||
// I have no idea how MAC OS X deals with multiple devices, so a quick workaround
|
||||
for (uiDevNr=0; uiDevNr<MAX_DEVICES; uiDevNr++)
|
||||
for (uiDevNr=0; uiDevNr<DRIVERS_MAX_DEVICES; uiDevNr++)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
strcpy(acConnect,SERIAL_STRING);
|
||||
|
@ -107,14 +113,14 @@ dev_info* arygon_connect(const nfc_device_desc_t* pndd)
|
|||
}
|
||||
#endif
|
||||
// Test if we have found a device
|
||||
if (uiDevNr == MAX_DEVICES) return INVALID_DEVICE_INFO;
|
||||
if (uiDevNr == DRIVERS_MAX_DEVICES) return NULL;
|
||||
} else {
|
||||
DBG("Connecting to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed);
|
||||
strcpy(acConnect,pndd->pcPort);
|
||||
sp = uart_open(acConnect);
|
||||
if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",acConnect);
|
||||
if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",acConnect);
|
||||
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return INVALID_DEVICE_INFO;
|
||||
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL;
|
||||
|
||||
uart_set_speed(sp, pndd->uiSpeed);
|
||||
}
|
||||
|
@ -122,24 +128,24 @@ dev_info* arygon_connect(const nfc_device_desc_t* pndd)
|
|||
DBG("Successfully connected to: %s",acConnect);
|
||||
|
||||
// We have a connection
|
||||
pdi = malloc(sizeof(dev_info));
|
||||
strcpy(pdi->acName,"ARYGON");
|
||||
pdi->ct = CT_PN532;
|
||||
pdi->ds = (dev_spec)sp;
|
||||
pdi->bActive = true;
|
||||
pdi->bCrc = true;
|
||||
pdi->bPar = true;
|
||||
pdi->ui8TxBits = 0;
|
||||
return pdi;
|
||||
pnd = malloc(sizeof(nfc_device_t));
|
||||
strcpy(pnd->acName,"ARYGON");
|
||||
pnd->nc = NC_PN532;
|
||||
pnd->nds = (nfc_device_spec_t)sp;
|
||||
pnd->bActive = true;
|
||||
pnd->bCrc = true;
|
||||
pnd->bPar = true;
|
||||
pnd->ui8TxBits = 0;
|
||||
return pnd;
|
||||
}
|
||||
|
||||
void arygon_disconnect(dev_info* pdi)
|
||||
void arygon_disconnect(nfc_device_t* pnd)
|
||||
{
|
||||
uart_close((serial_port)pdi->ds);
|
||||
free(pdi);
|
||||
uart_close((serial_port)pnd->nds);
|
||||
free(pnd);
|
||||
}
|
||||
|
||||
bool arygon_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool arygon_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
byte_t abtTxBuf[BUFFER_LENGTH] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||
byte_t abtRxBuf[BUFFER_LENGTH];
|
||||
|
@ -167,8 +173,8 @@ bool arygon_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTx
|
|||
printf(" TX: ");
|
||||
print_hex(abtTxBuf,szTxLen+8);
|
||||
#endif
|
||||
if (!uart_send((serial_port)ds,abtTxBuf,szTxLen+8)) {
|
||||
ERR("Unable to transmit data. (TX)");
|
||||
if (!uart_send((serial_port)nds,abtTxBuf,szTxLen+8)) {
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -187,8 +193,8 @@ bool arygon_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTx
|
|||
* For more information, see Issue 23 on development site : http://code.google.com/p/libnfc/issues/detail?id=23
|
||||
*/
|
||||
|
||||
if (!uart_receive((serial_port)ds,abtRxBuf,&szRxBufLen)) {
|
||||
ERR("Unable to receive data. (RX)");
|
||||
if (!uart_receive((serial_port)nds,abtRxBuf,&szRxBufLen)) {
|
||||
ERR("%s", "Unable to receive data. (RX)");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,18 +21,19 @@
|
|||
* @brief
|
||||
*/
|
||||
|
||||
#ifndef _LIBNFC_DEV_ARYGON_H_
|
||||
#define _LIBNFC_DEV_ARYGON_H_
|
||||
#ifndef __NFC_DRIVER_ARYGON_H__
|
||||
#define __NFC_DRIVER_ARYGON_H__
|
||||
|
||||
#include "defines.h"
|
||||
#include "types.h"
|
||||
#include "nfc-types.h"
|
||||
|
||||
#define ARYGON_DRIVER_NAME "ARYGON"
|
||||
|
||||
// Functions used by developer to handle connection to this device
|
||||
dev_info* arygon_connect(const nfc_device_desc_t* pndd);
|
||||
void arygon_disconnect(dev_info* pdi);
|
||||
nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd);
|
||||
void arygon_disconnect(nfc_device_t* pnd);
|
||||
|
||||
// Callback function used by libnfc to transmit commands to the PN53X chip
|
||||
bool arygon_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool arygon_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
||||
#endif // _LIBNFC_DEV_ARYGON_H_
|
||||
#endif // ! __NFC_DRIVER_ARYGON_H__
|
||||
|
||||
|
|
|
@ -17,23 +17,26 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*
|
||||
* @file pn531.c
|
||||
* @brief
|
||||
* @file pn531_usb.c
|
||||
* @brief Driver for PN531 chip using USB
|
||||
*/
|
||||
|
||||
/*
|
||||
Thanks to d18c7db and Okko for example code
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <usb.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "pn531.h"
|
||||
#include "messages.h"
|
||||
#include "pn531_usb.h"
|
||||
#include "../drivers.h"
|
||||
|
||||
#include "nfc-messages.h"
|
||||
#include "../bitutils.h"
|
||||
|
||||
#define BUFFER_LENGTH 256
|
||||
#define USB_TIMEOUT 30000
|
||||
|
@ -42,10 +45,10 @@ typedef struct {
|
|||
usb_dev_handle* pudh;
|
||||
uint32_t uiEndPointIn;
|
||||
uint32_t uiEndPointOut;
|
||||
} dev_spec_pn531;
|
||||
} usb_spec_t;
|
||||
|
||||
// Find transfer endpoints for bulk transfers
|
||||
static void get_end_points(struct usb_device *dev, dev_spec_pn531* pdsp)
|
||||
static void get_end_points(struct usb_device *dev, usb_spec_t* pus)
|
||||
{
|
||||
uint32_t uiIndex;
|
||||
uint32_t uiEndPoint;
|
||||
|
@ -66,7 +69,7 @@ static void get_end_points(struct usb_device *dev, dev_spec_pn531* pdsp)
|
|||
#ifdef DEBUG
|
||||
printf("Bulk endpoint in : 0x%02X\n", uiEndPoint);
|
||||
#endif
|
||||
pdsp->uiEndPointIn = uiEndPoint;
|
||||
pus->uiEndPointIn = uiEndPoint;
|
||||
}
|
||||
|
||||
// Test if we dealing with a bulk OUT endpoint
|
||||
|
@ -75,12 +78,12 @@ static void get_end_points(struct usb_device *dev, dev_spec_pn531* pdsp)
|
|||
#ifdef DEBUG
|
||||
printf("Bulk endpoint in : 0x%02X\n", uiEndPoint);
|
||||
#endif
|
||||
pdsp->uiEndPointOut = uiEndPoint;
|
||||
pus->uiEndPointOut = uiEndPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dev_info* pn531_connect(const nfc_device_desc_t* pndd)
|
||||
nfc_device_t* pn531_usb_connect(const nfc_device_desc_t* pndd)
|
||||
{
|
||||
int idvendor = 0x04CC;
|
||||
int idproduct = 0x0531;
|
||||
|
@ -88,24 +91,24 @@ dev_info* pn531_connect(const nfc_device_desc_t* pndd)
|
|||
int idproduct_alt = 0x0193;
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
dev_info* pdi = INVALID_DEVICE_INFO;
|
||||
dev_spec_pn531* pdsp;
|
||||
dev_spec_pn531 dsp;
|
||||
nfc_device_t* pnd = NULL;
|
||||
usb_spec_t* pus;
|
||||
usb_spec_t us;
|
||||
uint32_t uiDevIndex;
|
||||
|
||||
dsp.uiEndPointIn = 0;
|
||||
dsp.uiEndPointOut = 0;
|
||||
dsp.pudh = NULL;
|
||||
us.uiEndPointIn = 0;
|
||||
us.uiEndPointOut = 0;
|
||||
us.pudh = NULL;
|
||||
|
||||
usb_init();
|
||||
if (usb_find_busses() < 0) return INVALID_DEVICE_INFO;
|
||||
if (usb_find_devices() < 0) return INVALID_DEVICE_INFO;
|
||||
if (usb_find_busses() < 0) return NULL;
|
||||
if (usb_find_devices() < 0) return NULL;
|
||||
|
||||
// Initialize the device index we are seaching for
|
||||
if( pndd == NULL ) {
|
||||
uiDevIndex = 0;
|
||||
} else {
|
||||
uiDevIndex = pndd->uiIndex;
|
||||
uiDevIndex = pndd->uiBusIndex;
|
||||
}
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next)
|
||||
|
@ -116,7 +119,7 @@ dev_info* pn531_connect(const nfc_device_desc_t* pndd)
|
|||
(idvendor_alt==dev->descriptor.idVendor && idproduct_alt==dev->descriptor.idProduct))
|
||||
{
|
||||
// Make sure there are 2 endpoints available
|
||||
if (dev->config->interface->altsetting->bNumEndpoints < 2) return pdi;
|
||||
if (dev->config->interface->altsetting->bNumEndpoints < 2) return pnd;
|
||||
|
||||
// Test if we are looking for this device according to the current index
|
||||
if (uiDevIndex != 0)
|
||||
|
@ -125,54 +128,60 @@ dev_info* pn531_connect(const nfc_device_desc_t* pndd)
|
|||
uiDevIndex--;
|
||||
continue;
|
||||
}
|
||||
DBG("Found PN531 device");
|
||||
DBG("%s", "Found PN531 device");
|
||||
|
||||
// Open the PN531 USB device
|
||||
dsp.pudh = usb_open(dev);
|
||||
us.pudh = usb_open(dev);
|
||||
|
||||
get_end_points(dev,&dsp);
|
||||
|
||||
if(usb_claim_interface(dsp.pudh,0) < 0)
|
||||
get_end_points(dev,&us);
|
||||
if(usb_set_configuration(us.pudh,1) < 0)
|
||||
{
|
||||
DBG("Can't claim interface");
|
||||
usb_close(dsp.pudh);
|
||||
DBG("%s", "Set config failed");
|
||||
usb_close(us.pudh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(usb_claim_interface(us.pudh,0) < 0)
|
||||
{
|
||||
DBG("%s", "Can't claim interface");
|
||||
usb_close(us.pudh);
|
||||
// don't return yet as there might be other readers on USB bus
|
||||
continue;
|
||||
}
|
||||
// Allocate memory for the device info and specification, fill it and return the info
|
||||
pdsp = malloc(sizeof(dev_spec_pn531));
|
||||
*pdsp = dsp;
|
||||
pdi = malloc(sizeof(dev_info));
|
||||
strcpy(pdi->acName,"PN531USB");
|
||||
pdi->ct = CT_PN531;
|
||||
pdi->ds = (dev_spec)pdsp;
|
||||
pdi->bActive = true;
|
||||
pdi->bCrc = true;
|
||||
pdi->bPar = true;
|
||||
pdi->ui8TxBits = 0;
|
||||
return pdi;
|
||||
pus = malloc(sizeof(usb_spec_t));
|
||||
*pus = us;
|
||||
pnd = malloc(sizeof(nfc_device_t));
|
||||
strcpy(pnd->acName,"PN531USB");
|
||||
pnd->nc = NC_PN531;
|
||||
pnd->nds = (nfc_device_spec_t)pus;
|
||||
pnd->bActive = true;
|
||||
pnd->bCrc = true;
|
||||
pnd->bPar = true;
|
||||
pnd->ui8TxBits = 0;
|
||||
return pnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pdi;
|
||||
return pnd;
|
||||
}
|
||||
|
||||
void pn531_disconnect(dev_info* pdi)
|
||||
void pn531_usb_disconnect(nfc_device_t* pnd)
|
||||
{
|
||||
dev_spec_pn531* pdsp = (dev_spec_pn531*)pdi->ds;
|
||||
usb_release_interface(pdsp->pudh,0);
|
||||
usb_close(pdsp->pudh);
|
||||
free(pdi->ds);
|
||||
free(pdi);
|
||||
usb_spec_t* pus = (usb_spec_t*)pnd->nds;
|
||||
usb_release_interface(pus->pudh,0);
|
||||
usb_close(pus->pudh);
|
||||
free(pnd->nds);
|
||||
free(pnd);
|
||||
}
|
||||
|
||||
bool pn531_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool pn531_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
size_t uiPos = 0;
|
||||
int ret = 0;
|
||||
byte_t abtTx[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||
byte_t abtRx[BUFFER_LENGTH];
|
||||
dev_spec_pn531* pdsp = (dev_spec_pn531*)ds;
|
||||
usb_spec_t* pus = (usb_spec_t*)nds;
|
||||
|
||||
// Packet length = data length (len) + checksum (1) + end of stream marker (1)
|
||||
abtTx[3] = szTxLen;
|
||||
|
@ -196,7 +205,7 @@ bool pn531_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxL
|
|||
print_hex(abtTx,szTxLen+7);
|
||||
#endif
|
||||
|
||||
ret = usb_bulk_write(pdsp->pudh, pdsp->uiEndPointOut, (char*)abtTx, szTxLen+7, USB_TIMEOUT);
|
||||
ret = usb_bulk_write(pus->pudh, pus->uiEndPointOut, (char*)abtTx, szTxLen+7, USB_TIMEOUT);
|
||||
if( ret < 0 )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
@ -205,7 +214,7 @@ bool pn531_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxL
|
|||
return false;
|
||||
}
|
||||
|
||||
ret = usb_bulk_read(pdsp->pudh, pdsp->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
ret = usb_bulk_read(pus->pudh, pus->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
if( ret < 0 )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
@ -221,7 +230,7 @@ bool pn531_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxL
|
|||
|
||||
if( ret == 6 )
|
||||
{
|
||||
ret = usb_bulk_read(pdsp->pudh, pdsp->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
ret = usb_bulk_read(pus->pudh, pus->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
if( ret < 0 )
|
||||
{
|
||||
#ifdef DEBUG
|
|
@ -17,25 +17,26 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*
|
||||
* @file pn531.h
|
||||
* @file pn531_usb.h
|
||||
* @brief
|
||||
*/
|
||||
|
||||
#ifndef _LIBNFC_DEV_PN531_H_
|
||||
#define _LIBNFC_DEV_PN531_H_
|
||||
#ifndef __NFC_DRIVER_PN531_USB_H__
|
||||
#define __NFC_DRIVER_PN531_USB_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "types.h"
|
||||
#include "nfc-types.h"
|
||||
|
||||
#define PN531_USB_DRIVER_NAME "PN531_USB"
|
||||
|
||||
// Functions used by developer to handle connection to this device
|
||||
dev_info* pn531_connect(const nfc_device_desc_t* pndd);
|
||||
void pn531_disconnect(dev_info* pdi);
|
||||
nfc_device_t* pn531_usb_connect(const nfc_device_desc_t* pndd);
|
||||
void pn531_usb_disconnect(nfc_device_t* pnd);
|
||||
|
||||
// Callback function used by libnfc to transmit commands to the PN53X chip
|
||||
bool pn531_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool pn531_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
||||
#endif // _LIBNFC_DEV_PN531_H_
|
||||
#endif // ! __NFC_DRIVER_PN531_USB_H__
|
||||
|
|
@ -20,11 +20,18 @@
|
|||
* @file pn532_uart.c
|
||||
* @brief
|
||||
*/
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pn532_uart.h"
|
||||
|
||||
#include "nfc-messages.h"
|
||||
|
||||
#include "../drivers.h"
|
||||
#include "../bitutils.h"
|
||||
|
||||
// Bus
|
||||
#include "uart.h"
|
||||
#include "messages.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SERIAL_STRING "COM"
|
||||
|
@ -47,21 +54,21 @@
|
|||
|
||||
#define SERIAL_DEFAULT_PORT_SPEED 115200
|
||||
|
||||
dev_info* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
||||
nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
||||
{
|
||||
uint32_t uiDevNr;
|
||||
serial_port sp;
|
||||
char acConnect[BUFFER_LENGTH];
|
||||
dev_info* pdi = INVALID_DEVICE_INFO;
|
||||
nfc_device_t* pnd = NULL;
|
||||
|
||||
if( pndd == NULL ) {
|
||||
#ifdef DISABLE_SERIAL_AUTOPROBE
|
||||
INFO("Sorry, serial auto-probing have been disabled at compile time.");
|
||||
return INVALID_DEVICE_INFO;
|
||||
return NULL;
|
||||
#else
|
||||
DBG("Trying to find ARYGON device on serial port: %s# at %d bauds.",SERIAL_STRING, SERIAL_DEFAULT_PORT_SPEED);
|
||||
// I have no idea how MAC OS X deals with multiple devices, so a quick workaround
|
||||
for (uiDevNr=0; uiDevNr<MAX_DEVICES; uiDevNr++)
|
||||
for (uiDevNr=0; uiDevNr<DRIVERS_MAX_DEVICES; uiDevNr++)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
strcpy(acConnect,SERIAL_STRING);
|
||||
|
@ -82,14 +89,14 @@ dev_info* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
|||
}
|
||||
#endif
|
||||
// Test if we have found a device
|
||||
if (uiDevNr == MAX_DEVICES) return INVALID_DEVICE_INFO;
|
||||
if (uiDevNr == DRIVERS_MAX_DEVICES) return NULL;
|
||||
} else {
|
||||
DBG("Connecting to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed);
|
||||
strcpy(acConnect,pndd->pcPort);
|
||||
sp = uart_open(acConnect);
|
||||
if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",acConnect);
|
||||
if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",acConnect);
|
||||
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return INVALID_DEVICE_INFO;
|
||||
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL;
|
||||
|
||||
uart_set_speed(sp, pndd->uiSpeed);
|
||||
}
|
||||
|
@ -103,7 +110,7 @@ dev_info* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
|||
delay_ms(10);
|
||||
|
||||
if (!uart_receive(sp,abtRxBuf,&szRxBufLen)) {
|
||||
ERR("Unable to receive data. (RX)");
|
||||
ERR("%s", "Unable to receive data. (RX)");
|
||||
return NULL;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
|
@ -114,24 +121,24 @@ dev_info* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
|||
DBG("Successfully connected to: %s",acConnect);
|
||||
|
||||
// We have a connection
|
||||
pdi = malloc(sizeof(dev_info));
|
||||
strcpy(pdi->acName,"PN532_UART");
|
||||
pdi->ct = CT_PN532;
|
||||
pdi->ds = (dev_spec)sp;
|
||||
pdi->bActive = true;
|
||||
pdi->bCrc = true;
|
||||
pdi->bPar = true;
|
||||
pdi->ui8TxBits = 0;
|
||||
return pdi;
|
||||
pnd = malloc(sizeof(nfc_device_t));
|
||||
strcpy(pnd->acName,"PN532_UART");
|
||||
pnd->nc = NC_PN532;
|
||||
pnd->nds = (nfc_device_spec_t)sp;
|
||||
pnd->bActive = true;
|
||||
pnd->bCrc = true;
|
||||
pnd->bPar = true;
|
||||
pnd->ui8TxBits = 0;
|
||||
return pnd;
|
||||
}
|
||||
|
||||
void pn532_uart_disconnect(dev_info* pdi)
|
||||
void pn532_uart_disconnect(nfc_device_t* pnd)
|
||||
{
|
||||
uart_close((serial_port)pdi->ds);
|
||||
free(pdi);
|
||||
uart_close((serial_port)pnd->nds);
|
||||
free(pnd);
|
||||
}
|
||||
|
||||
bool pn532_uart_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool pn532_uart_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
byte_t abtTxBuf[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||
byte_t abtRxBuf[BUFFER_LENGTH];
|
||||
|
@ -159,8 +166,8 @@ bool pn532_uart_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t
|
|||
printf(" TX: ");
|
||||
print_hex(abtTxBuf,szTxLen+7);
|
||||
#endif
|
||||
if (!uart_send((serial_port)ds,abtTxBuf,szTxLen+7)) {
|
||||
ERR("Unable to transmit data. (TX)");
|
||||
if (!uart_send((serial_port)nds,abtTxBuf,szTxLen+7)) {
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -174,8 +181,8 @@ bool pn532_uart_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t
|
|||
*/
|
||||
delay_ms(30);
|
||||
|
||||
if (!uart_receive((serial_port)ds,abtRxBuf,&szRxBufLen)) {
|
||||
ERR("Unable to receive data. (RX)");
|
||||
if (!uart_receive((serial_port)nds,abtRxBuf,&szRxBufLen)) {
|
||||
ERR("%s", "Unable to receive data. (RX)");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,18 +21,19 @@
|
|||
* @brief
|
||||
*/
|
||||
|
||||
#ifndef _LIBNFC_DEV_PN532_UART_H_
|
||||
#define _LIBNFC_DEV_PN532_UART_H_
|
||||
#ifndef __NFC_DRIVER_PN532_UART_H__
|
||||
#define __NFC_DRIVER_PN532_UART_H__
|
||||
|
||||
#include "defines.h"
|
||||
#include "types.h"
|
||||
#include "nfc-types.h"
|
||||
|
||||
#define PN532_UART_DRIVER_NAME "PN532_UART"
|
||||
|
||||
// Functions used by developer to handle connection to this device
|
||||
dev_info* pn532_uart_connect(const nfc_device_desc_t* pndd);
|
||||
void pn532_uart_disconnect(dev_info* pdi);
|
||||
nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd);
|
||||
void pn532_uart_disconnect(nfc_device_t* pnd);
|
||||
|
||||
// Callback function used by libnfc to transmit commands to the PN53X chip
|
||||
bool pn532_uart_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool pn532_uart_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
||||
#endif // _LIBNFC_DEV_PN532_UART_H_
|
||||
#endif // ! __NFC_DRIVER_PN532_UART_H__
|
||||
|
||||
|
|
|
@ -17,21 +17,23 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*
|
||||
* @file pn533.c
|
||||
* @brief
|
||||
* @file pn533_usb.c
|
||||
* @brief Driver for PN533 chip using USB
|
||||
*/
|
||||
|
||||
/*
|
||||
Thanks to d18c7db and Okko for example code
|
||||
*/
|
||||
#include "pn533.h"
|
||||
|
||||
#include <usb.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <usb.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "messages.h"
|
||||
#include "pn533_usb.h"
|
||||
#include "../drivers.h"
|
||||
|
||||
#include "nfc-messages.h"
|
||||
|
||||
#define BUFFER_LENGTH 256
|
||||
#define USB_TIMEOUT 30000
|
||||
|
@ -40,10 +42,10 @@ typedef struct {
|
|||
usb_dev_handle* pudh;
|
||||
uint32_t uiEndPointIn;
|
||||
uint32_t uiEndPointOut;
|
||||
} dev_spec_pn533;
|
||||
} usb_spec_t;
|
||||
|
||||
// Find transfer endpoints for bulk transfers
|
||||
static void get_end_points(struct usb_device *dev, dev_spec_pn533* pdsp)
|
||||
static void get_end_points(struct usb_device *dev, usb_spec_t* pus)
|
||||
{
|
||||
uint32_t uiIndex;
|
||||
uint32_t uiEndPoint;
|
||||
|
@ -64,7 +66,7 @@ static void get_end_points(struct usb_device *dev, dev_spec_pn533* pdsp)
|
|||
#ifdef DEBUG
|
||||
printf("Bulk endpoint in : 0x%02X\n", uiEndPoint);
|
||||
#endif
|
||||
pdsp->uiEndPointIn = uiEndPoint;
|
||||
pus->uiEndPointIn = uiEndPoint;
|
||||
}
|
||||
|
||||
// Test if we dealing with a bulk OUT endpoint
|
||||
|
@ -73,48 +75,45 @@ static void get_end_points(struct usb_device *dev, dev_spec_pn533* pdsp)
|
|||
#ifdef DEBUG
|
||||
printf("Bulk endpoint in : 0x%02X\n", uiEndPoint);
|
||||
#endif
|
||||
pdsp->uiEndPointOut = uiEndPoint;
|
||||
pus->uiEndPointOut = uiEndPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dev_info* pn533_connect(const nfc_device_desc_t* pndd)
|
||||
nfc_device_t* pn533_usb_connect(const nfc_device_desc_t* pndd)
|
||||
{
|
||||
int idvendor = 0x04cc;
|
||||
int idproduct = 0x2533;
|
||||
int idvendor_alt = 0x04e6;
|
||||
int idproduct_alt = 0x5591;
|
||||
int idvendor = 0x04e6;
|
||||
int idproduct = 0x5591;
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
dev_info* pdi = INVALID_DEVICE_INFO;
|
||||
dev_spec_pn533* pdsp;
|
||||
dev_spec_pn533 dsp;
|
||||
nfc_device_t* pnd = NULL;
|
||||
usb_spec_t* pus;
|
||||
usb_spec_t us;
|
||||
uint32_t uiDevIndex;
|
||||
|
||||
dsp.uiEndPointIn = 0;
|
||||
dsp.uiEndPointOut = 0;
|
||||
dsp.pudh = NULL;
|
||||
us.uiEndPointIn = 0;
|
||||
us.uiEndPointOut = 0;
|
||||
us.pudh = NULL;
|
||||
|
||||
usb_init();
|
||||
if (usb_find_busses() < 0) return INVALID_DEVICE_INFO;
|
||||
if (usb_find_devices() < 0) return INVALID_DEVICE_INFO;
|
||||
if (usb_find_busses() < 0) return NULL;
|
||||
if (usb_find_devices() < 0) return NULL;
|
||||
|
||||
// Initialize the device index we are seaching for
|
||||
if( pndd == NULL ) {
|
||||
uiDevIndex = 0;
|
||||
} else {
|
||||
uiDevIndex = pndd->uiIndex;
|
||||
uiDevIndex = pndd->uiBusIndex;
|
||||
}
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next)
|
||||
{
|
||||
for (dev = bus->devices; dev; dev = dev->next)
|
||||
{
|
||||
if ((idvendor==dev->descriptor.idVendor && idproduct==dev->descriptor.idProduct) ||
|
||||
(idvendor_alt==dev->descriptor.idVendor && idproduct_alt==dev->descriptor.idProduct))
|
||||
if (idvendor==dev->descriptor.idVendor && idproduct==dev->descriptor.idProduct)
|
||||
{
|
||||
// Make sure there are 2 endpoints available
|
||||
if (dev->config->interface->altsetting->bNumEndpoints < 2) return pdi;
|
||||
if (dev->config->interface->altsetting->bNumEndpoints < 2) return pnd;
|
||||
|
||||
// Test if we are looking for this device according to the current index
|
||||
if (uiDevIndex != 0)
|
||||
|
@ -123,54 +122,60 @@ dev_info* pn533_connect(const nfc_device_desc_t* pndd)
|
|||
uiDevIndex--;
|
||||
continue;
|
||||
}
|
||||
DBG("Found PN533 device");
|
||||
DBG("%s", "Found PN533 device");
|
||||
|
||||
// Open the PN533 USB device
|
||||
dsp.pudh = usb_open(dev);
|
||||
us.pudh = usb_open(dev);
|
||||
|
||||
get_end_points(dev,&dsp);
|
||||
|
||||
if(usb_claim_interface(dsp.pudh,0) < 0)
|
||||
get_end_points(dev,&us);
|
||||
if(usb_set_configuration(us.pudh,1) < 0)
|
||||
{
|
||||
DBG("Can't claim interface");
|
||||
usb_close(dsp.pudh);
|
||||
DBG("%s", "Setting config failed");
|
||||
usb_close(us.pudh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(usb_claim_interface(us.pudh,0) < 0)
|
||||
{
|
||||
DBG("%s", "Can't claim interface");
|
||||
usb_close(us.pudh);
|
||||
// don't return yet as there might be other readers on USB bus
|
||||
continue;
|
||||
}
|
||||
// Allocate memory for the device info and specification, fill it and return the info
|
||||
pdsp = malloc(sizeof(dev_spec_pn533));
|
||||
*pdsp = dsp;
|
||||
pdi = malloc(sizeof(dev_info));
|
||||
strcpy(pdi->acName,"PN533USB");
|
||||
pdi->ct = CT_PN533;
|
||||
pdi->ds = (dev_spec)pdsp;
|
||||
pdi->bActive = true;
|
||||
pdi->bCrc = true;
|
||||
pdi->bPar = true;
|
||||
pdi->ui8TxBits = 0;
|
||||
return pdi;
|
||||
pus = malloc(sizeof(usb_spec_t));
|
||||
*pus = us;
|
||||
pnd = malloc(sizeof(nfc_device_t));
|
||||
strcpy(pnd->acName,"PN533USB");
|
||||
pnd->nc = NC_PN533;
|
||||
pnd->nds = (nfc_device_spec_t)pus;
|
||||
pnd->bActive = true;
|
||||
pnd->bCrc = true;
|
||||
pnd->bPar = true;
|
||||
pnd->ui8TxBits = 0;
|
||||
return pnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pdi;
|
||||
return pnd;
|
||||
}
|
||||
|
||||
void pn533_disconnect(dev_info* pdi)
|
||||
void pn533_usb_disconnect(nfc_device_t* pnd)
|
||||
{
|
||||
dev_spec_pn533* pdsp = (dev_spec_pn533*)pdi->ds;
|
||||
usb_release_interface(pdsp->pudh,0);
|
||||
usb_close(pdsp->pudh);
|
||||
free(pdi->ds);
|
||||
free(pdi);
|
||||
usb_spec_t* pus = (usb_spec_t*)pnd->nds;
|
||||
usb_release_interface(pus->pudh,0);
|
||||
usb_close(pus->pudh);
|
||||
free(pnd->nds);
|
||||
free(pnd);
|
||||
}
|
||||
|
||||
bool pn533_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool pn533_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
size_t uiPos = 0;
|
||||
int ret = 0;
|
||||
byte_t abtTx[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||
byte_t abtRx[BUFFER_LENGTH];
|
||||
dev_spec_pn533* pdsp = (dev_spec_pn533*)ds;
|
||||
usb_spec_t* pus = (usb_spec_t*)nds;
|
||||
|
||||
// Packet length = data length (len) + checksum (1) + end of stream marker (1)
|
||||
abtTx[3] = szTxLen;
|
||||
|
@ -194,7 +199,7 @@ bool pn533_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxL
|
|||
print_hex(abtTx,szTxLen+7);
|
||||
#endif
|
||||
|
||||
ret = usb_bulk_write(pdsp->pudh, pdsp->uiEndPointOut, (char*)abtTx, szTxLen+7, USB_TIMEOUT);
|
||||
ret = usb_bulk_write(pus->pudh, pus->uiEndPointOut, (char*)abtTx, szTxLen+7, USB_TIMEOUT);
|
||||
if( ret < 0 )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
@ -203,7 +208,7 @@ bool pn533_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxL
|
|||
return false;
|
||||
}
|
||||
|
||||
ret = usb_bulk_read(pdsp->pudh, pdsp->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
ret = usb_bulk_read(pus->pudh, pus->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
if( ret < 0 )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
@ -219,7 +224,7 @@ bool pn533_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxL
|
|||
|
||||
if( ret == 6 )
|
||||
{
|
||||
ret = usb_bulk_read(pdsp->pudh, pdsp->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
ret = usb_bulk_read(pus->pudh, pus->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
if( ret < 0 )
|
||||
{
|
||||
#ifdef DEBUG
|
|
@ -17,22 +17,23 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*
|
||||
* @file pn533.h
|
||||
* @file pn533_usb.h
|
||||
* @brief
|
||||
*/
|
||||
|
||||
#ifndef _LIBNFC_DEV_PN533_H_
|
||||
#define _LIBNFC_DEV_PN533_H_
|
||||
#ifndef __NFC_DRIVER_PN533_USB_H__
|
||||
#define __NFC_DRIVER_PN533_USB_H__
|
||||
|
||||
#include "defines.h"
|
||||
#include "types.h"
|
||||
#include "nfc-types.h"
|
||||
|
||||
#define PN533_USB_DRIVER_NAME "PN533_USB"
|
||||
|
||||
// Functions used by developer to handle connection to this device
|
||||
dev_info* pn533_connect(const nfc_device_desc_t* pndd);
|
||||
void pn533_disconnect(dev_info* pdi);
|
||||
nfc_device_t* pn533_usb_connect(const nfc_device_desc_t* pndd);
|
||||
void pn533_usb_disconnect(nfc_device_t* pnd);
|
||||
|
||||
// Callback function used by libnfc to transmit commands to the PN53X chip
|
||||
bool pn533_transceive(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool pn533_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
||||
#endif // _LIBNFC_DEV_PN533_H_
|
||||
#endif // ! __NFC_DRIVER_PN533_USB_H__
|
||||
|
|
@ -17,12 +17,12 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*
|
||||
* @file types.h
|
||||
* @brief
|
||||
* @file nfc-types.h
|
||||
* @brief Define NFC types
|
||||
*/
|
||||
|
||||
#ifndef _LIBNFC_TYPES_H_
|
||||
#define _LIBNFC_TYPES_H_
|
||||
#ifndef __NFC_TYPES_H__
|
||||
#define __NFC_TYPES_H__
|
||||
|
||||
/**
|
||||
* @file types.h
|
||||
|
@ -34,20 +34,21 @@
|
|||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
typedef uint8_t byte_t;
|
||||
|
||||
typedef enum {
|
||||
CT_PN531 = 0x10,
|
||||
CT_PN532 = 0x20,
|
||||
CT_PN533 = 0x30,
|
||||
} chip_type;
|
||||
NC_PN531 = 0x10,
|
||||
NC_PN532 = 0x20,
|
||||
NC_PN533 = 0x30,
|
||||
} nfc_chip_t;
|
||||
|
||||
struct driver_callbacks; // Prototype the callback struct
|
||||
|
||||
typedef void* nfc_device_spec_t; // Device connection specification
|
||||
|
||||
#define DEVICE_NAME_LENGTH 256
|
||||
/**
|
||||
* @struct dev_info
|
||||
* @struct nfc_device_t
|
||||
* @brief NFC device information
|
||||
*/
|
||||
typedef struct {
|
||||
|
@ -56,9 +57,9 @@ typedef struct {
|
|||
/** Device name string, including device wrapper firmware */
|
||||
char acName[DEVICE_NAME_LENGTH];
|
||||
/** PN53X chip type, this is useful for some "bug" work-arounds */
|
||||
chip_type ct;
|
||||
nfc_chip_t nc;
|
||||
/** Pointer to the device connection specification */
|
||||
dev_spec ds;
|
||||
nfc_device_spec_t nds;
|
||||
/** This represents if the PN53X device was initialized succesful */
|
||||
bool bActive;
|
||||
/** Is the crc automaticly added, checked and removed from the frames */
|
||||
|
@ -67,7 +68,8 @@ typedef struct {
|
|||
bool bPar;
|
||||
/** The last tx bits setting, we need to reset this if it does not apply anymore */
|
||||
uint8_t ui8TxBits;
|
||||
} dev_info;
|
||||
} nfc_device_t;
|
||||
|
||||
|
||||
/**
|
||||
* @struct nfc_device_desc_t
|
||||
|
@ -76,81 +78,87 @@ typedef struct {
|
|||
* This struct is used to try to connect to a specified nfc device when nfc_connect(...)
|
||||
*/
|
||||
typedef struct {
|
||||
/** Driver name */
|
||||
/** Device name (e.g. "ACS ACR 38U-CCID 00 00") */
|
||||
char acDevice[BUFSIZ];
|
||||
/** Driver name (e.g. "PN532_UART")*/
|
||||
char* pcDriver;
|
||||
/** Port (i.e. /dev/ttyUSB2) */
|
||||
/** Port (e.g. "/dev/ttyUSB0") */
|
||||
char* pcPort;
|
||||
/** Port speed (i.e. 115200) */
|
||||
/** Port speed (e.g. "115200") */
|
||||
uint32_t uiSpeed;
|
||||
/** Device index for backward compatibility (used to choose one specific device in USB or PSCS devices list) */
|
||||
uint32_t uiIndex;
|
||||
uint32_t uiBusIndex;
|
||||
} nfc_device_desc_t;
|
||||
|
||||
/**
|
||||
* @struct driver_callbacks
|
||||
* @brief NFC defice callbacks
|
||||
* @brief Generic structure to handle NFC device functions.
|
||||
*/
|
||||
struct driver_callbacks {
|
||||
/** Driver name */
|
||||
const char* acDriver;
|
||||
/** Pick devices callback */
|
||||
nfc_device_desc_t *(*pick_device)(void);
|
||||
/** List devices callback */
|
||||
bool (*list_devices)(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
/** Connect callback */
|
||||
dev_info* (*connect)(const nfc_device_desc_t* pndd);
|
||||
nfc_device_t* (*connect)(const nfc_device_desc_t* pndd);
|
||||
/** Transceive callback */
|
||||
bool (*transceive)(const dev_spec ds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool (*transceive)(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
/** Disconnect callback */
|
||||
void (*disconnect)(dev_info* pdi);
|
||||
void (*disconnect)(nfc_device_t* pnd);
|
||||
};
|
||||
|
||||
// Compiler directive, set struct alignment to 1 byte_t for compatibility
|
||||
#pragma pack(1)
|
||||
|
||||
/**
|
||||
* @enum dev_config_option
|
||||
* @enum nfc_device_option_t
|
||||
* @brief NFC device option
|
||||
*/
|
||||
typedef enum {
|
||||
/** Let the PN53X chip handle the CRC bytes. This means that the chip appends the CRC bytes to the frames that are transmitted. It will parse the last bytes from received frames as incoming CRC bytes. They will be verified against the used modulation and protocol. If an frame is expected with incorrect CRC bytes this option should be disabled. Example frames where this is useful are the ATQA and UID+BCC that are transmitted without CRC bytes during the anti-collision phase of the ISO14443-A protocol. */
|
||||
DCO_HANDLE_CRC = 0x00,
|
||||
NDO_HANDLE_CRC = 0x00,
|
||||
/** Parity bits in the network layer of ISO14443-A are by default generated and validated in the PN53X chip. This is a very convenient feature. On certain times though it is useful to get full control of the transmitted data. The proprietary MIFARE Classic protocol uses for example custom (encrypted) parity bits. For interoperability it is required to be completely compatible, including the arbitrary parity bits. When this option is disabled, the functions to communicating bits should be used. */
|
||||
DCO_HANDLE_PARITY = 0x01,
|
||||
NDO_HANDLE_PARITY = 0x01,
|
||||
/** This option can be used to enable or disable the electronic field of the NFC device. */
|
||||
DCO_ACTIVATE_FIELD = 0x10,
|
||||
NDO_ACTIVATE_FIELD = 0x10,
|
||||
/** The internal CRYPTO1 co-processor can be used to transmit messages encrypted. This option is automatically activated after a successful MIFARE Classic authentication. */
|
||||
DCO_ACTIVATE_CRYPTO1 = 0x11,
|
||||
NDO_ACTIVATE_CRYPTO1 = 0x11,
|
||||
/** The default configuration defines that the PN53X chip will try indefinitely to invite a tag in the field to respond. This could be desired when it is certain a tag will enter the field. On the other hand, when this is uncertain, it will block the application. This option could best be compared to the (NON)BLOCKING option used by (socket)network programming. */
|
||||
DCO_INFINITE_SELECT = 0x20,
|
||||
NDO_INFINITE_SELECT = 0x20,
|
||||
/** If this option is enabled, frames that carry less than 4 bits are allowed. According to the standards these frames should normally be handles as invalid frames. */
|
||||
DCO_ACCEPT_INVALID_FRAMES = 0x30,
|
||||
NDO_ACCEPT_INVALID_FRAMES = 0x30,
|
||||
/** If the NFC device should only listen to frames, it could be useful to let it gather multiple frames in a sequence. They will be stored in the internal FIFO of the PN53X chip. This could be retrieved by using the receive data functions. Note that if the chip runs out of bytes (FIFO = 64 bytes long), it will overwrite the first received frames, so quick retrieving of the received data is desirable. */
|
||||
DCO_ACCEPT_MULTIPLE_FRAMES = 0x31
|
||||
}dev_config_option;
|
||||
NDO_ACCEPT_MULTIPLE_FRAMES = 0x31
|
||||
} nfc_device_option_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// nfc_reader_list_passive - using InListPassiveTarget
|
||||
|
||||
/**
|
||||
* @enum init_modulation
|
||||
* @enum nfc_modulation_t
|
||||
* @brief NFC modulation
|
||||
*/
|
||||
typedef enum {
|
||||
/** ISO14443-A (NXP MIFARE) http://en.wikipedia.org/wiki/MIFARE */
|
||||
IM_ISO14443A_106 = 0x00,
|
||||
NM_ISO14443A_106 = 0x00,
|
||||
/** JIS X 6319-4 (Sony Felica) http://en.wikipedia.org/wiki/FeliCa */
|
||||
IM_FELICA_212 = 0x01,
|
||||
NM_FELICA_212 = 0x01,
|
||||
/** JIS X 6319-4 (Sony Felica) http://en.wikipedia.org/wiki/FeliCa */
|
||||
IM_FELICA_424 = 0x02,
|
||||
NM_FELICA_424 = 0x02,
|
||||
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 */
|
||||
IM_ISO14443B_106 = 0x03,
|
||||
NM_ISO14443B_106 = 0x03,
|
||||
/** Jewel Topaz (Innovision Research & Development) */
|
||||
IM_JEWEL_106 = 0x04,
|
||||
NM_JEWEL_106 = 0x04,
|
||||
/** Active DEP */
|
||||
IM_ACTIVE_DEP = 0x05,
|
||||
NM_ACTIVE_DEP = 0x05,
|
||||
/** Passive DEP */
|
||||
IM_PASSIVE_DEP = 0x06,
|
||||
}init_modulation;
|
||||
NM_PASSIVE_DEP = 0x06
|
||||
} nfc_modulation_t;
|
||||
|
||||
/**
|
||||
* @struct tag_info_dep
|
||||
* @struct nfc_target_info_t_dep
|
||||
* @brief NFC tag information in Data Exchange Protocol
|
||||
*/
|
||||
typedef struct {
|
||||
|
@ -158,10 +166,10 @@ typedef struct {
|
|||
byte_t btDID;
|
||||
byte_t btBSt;
|
||||
byte_t btBRt;
|
||||
}tag_info_dep;
|
||||
} nfc_dep_info_t;
|
||||
|
||||
/**
|
||||
* @struct tag_info_iso14443a
|
||||
* @struct nfc_target_info_t_iso14443a
|
||||
* @brief NFC ISO14443A tag (MIFARE) information
|
||||
*/
|
||||
typedef struct {
|
||||
|
@ -171,10 +179,10 @@ typedef struct {
|
|||
byte_t abtUid[10];
|
||||
size_t szAtsLen;
|
||||
byte_t abtAts[36];
|
||||
}tag_info_iso14443a;
|
||||
} nfc_iso14443a_info_t;
|
||||
|
||||
/**
|
||||
* @struct tag_info_felica
|
||||
* @struct nfc_target_info_t_felica
|
||||
* @brief NFC FeLiCa tag information
|
||||
*/
|
||||
typedef struct {
|
||||
|
@ -183,10 +191,10 @@ typedef struct {
|
|||
byte_t abtId[8];
|
||||
byte_t abtPad[8];
|
||||
byte_t abtSysCode[2];
|
||||
}tag_info_felica;
|
||||
} nfc_felica_info_t;
|
||||
|
||||
/**
|
||||
* @struct tag_info_iso14443b
|
||||
* @struct nfc_target_info_t_iso14443b
|
||||
* @brief NFC ISO14443B tag information
|
||||
*/
|
||||
typedef struct {
|
||||
|
@ -199,28 +207,28 @@ typedef struct {
|
|||
byte_t btCid;
|
||||
size_t szInfLen;
|
||||
byte_t abtInf[64];
|
||||
}tag_info_iso14443b;
|
||||
} nfc_iso14443b_info_t;
|
||||
|
||||
/**
|
||||
* @struct tag_info_jewel
|
||||
* @struct nfc_target_info_t_jewel
|
||||
* @brief NFC Jewel tag information
|
||||
*/
|
||||
typedef struct {
|
||||
byte_t btSensRes[2];
|
||||
byte_t btId[4];
|
||||
}tag_info_jewel;
|
||||
} nfc_jewel_info_t;
|
||||
|
||||
/**
|
||||
* @union tag_info
|
||||
* @union nfc_target_info_t
|
||||
* @brief Union between all kind of tags information structures.
|
||||
*/
|
||||
typedef union {
|
||||
tag_info_iso14443a tia;
|
||||
tag_info_felica tif;
|
||||
tag_info_iso14443b tib;
|
||||
tag_info_jewel tij;
|
||||
tag_info_dep tid;
|
||||
}tag_info;
|
||||
nfc_iso14443a_info_t nai;
|
||||
nfc_felica_info_t nfi;
|
||||
nfc_iso14443b_info_t nbi;
|
||||
nfc_jewel_info_t nji;
|
||||
nfc_dep_info_t ndi;
|
||||
} nfc_target_info_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// InDataExchange, MIFARE Classic card
|
||||
|
@ -233,7 +241,7 @@ typedef enum {
|
|||
MC_TRANSFER = 0xB0,
|
||||
MC_DECREMENT = 0xC0,
|
||||
MC_INCREMENT = 0xC1,
|
||||
MC_STORE = 0xC2,
|
||||
MC_STORE = 0xC2
|
||||
}mifare_cmd;
|
||||
|
||||
// MIFARE Classic command params
|
580
src/lib/nfc.c
580
src/lib/nfc.c
File diff suppressed because it is too large
Load diff
117
src/lib/nfc.h
117
src/lib/nfc.h
|
@ -29,102 +29,111 @@
|
|||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "types.h"
|
||||
|
||||
#include "nfc-types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define NFCAPI extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
/**
|
||||
* @fn dev_info* nfc_connect(nfc_device_desc_t* pndd)
|
||||
* @fn void nfc_list_devices(nfc_device_desc_t *pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
* @brief Probe for discoverable supported devices (ie. only available for some drivers)
|
||||
* @param pnddDevices Array of nfc_device_desc_t previously allocated by the caller.
|
||||
* @param szDevices size of the pnddDevices array.
|
||||
* @param pszDeviceFound number of devices found.
|
||||
*/
|
||||
void nfc_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
|
||||
/**
|
||||
* @fn nfc_device_t* nfc_connect(nfc_device_desc_t* pndd)
|
||||
* @brief Connect to a NFC device
|
||||
* @param pndd Device description if specific device is wanted, NULL otherwise
|
||||
* @return Returns pointer to a dev_info struct if successfull; otherwise returns INVALID_DEVICE_INFO value.
|
||||
* @return Returns pointer to a nfc_device_t struct if successfull; otherwise returns NULL value.
|
||||
*
|
||||
* If \a pndd is NULL, the first available NFC device is claimed by libnfc.
|
||||
* It will automatically search the system using all available drivers to determine a device is free.
|
||||
*
|
||||
* If \a pndd is passed then libnfc will try to claim the right device using information provided by this struct.
|
||||
*
|
||||
* When it has successfully claimed a NFC device, memory is allocated to save the device information. It will return a pointer to a dev_info struct.
|
||||
* When it has successfully claimed a NFC device, memory is allocated to save the device information. It will return a pointer to a nfc_device_t struct.
|
||||
* This pointer should be supplied by every next function of libnfc that should perform an action with this device.
|
||||
*/
|
||||
dev_info* nfc_connect(nfc_device_desc_t* pndd);
|
||||
nfc_device_t* nfc_connect(nfc_device_desc_t* pndd);
|
||||
|
||||
/**
|
||||
* @fn void nfc_disconnect(dev_info* pdi)
|
||||
* @fn void nfc_disconnect(nfc_device_t* pnd)
|
||||
* @brief Disconnect from a NFC device
|
||||
* @param pdi dev_info struct pointer that represent currently used device
|
||||
* @param pnd nfc_device_t struct pointer that represent currently used device
|
||||
*
|
||||
* Initiator is disconnected and the device, including allocated dev_info struct, is released.
|
||||
* Initiator is disconnected and the device, including allocated nfc_device_t struct, is released.
|
||||
*/
|
||||
void nfc_disconnect(dev_info* pdi);
|
||||
void nfc_disconnect(nfc_device_t* pnd);
|
||||
|
||||
/**
|
||||
* @fn nfc_configure(dev_info* pdi, const dev_config_option dco, const bool bEnable)
|
||||
* @fn nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool bEnable)
|
||||
* @brief Configure advanced NFC device settings
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
* @param pdi dev_info struct pointer that represent currently used device
|
||||
* @param dco dev_config_option struct that contains options to set to device
|
||||
* @param pnd nfc_device_t struct pointer that represent currently used device
|
||||
* @param ndo nfc_device_option_t struct that contains options to set to device
|
||||
* @param bEnable boolean
|
||||
*
|
||||
* Configures parameters and registers that control for example timing, modulation, frame and error handling.
|
||||
* There are different categories for configuring the PN53X chip features (handle, activate, infinite and accept).
|
||||
* These are defined to organize future settings that will become available when they are needed.
|
||||
*/
|
||||
bool nfc_configure(dev_info* pdi, const dev_config_option dco, const bool bEnable);
|
||||
bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool bEnable);
|
||||
|
||||
/**
|
||||
* @fn nfc_initiator_init(const dev_info* pdi)
|
||||
* @fn nfc_initiator_init(const nfc_device_t* pnd)
|
||||
* @brief Initialize NFC device as initiator (reader)
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
* @param pdi dev_info struct pointer that represent currently used device
|
||||
* @param pnd nfc_device_t struct pointer that represent currently used device
|
||||
*
|
||||
* The NFC device is configured to function as RFID reader. After initialization it can be used to communicate to passive RFID tags and active NFC devices. The reader will act as initiator to communicate peer 2 peer (NFCIP) to other active NFC devices.
|
||||
*/
|
||||
bool nfc_initiator_init(const dev_info* pdi);
|
||||
bool nfc_initiator_init(const nfc_device_t* pnd);
|
||||
|
||||
/**
|
||||
* @fn nfc_initiator_select_tag(const dev_info* pdi, const init_modulation im, const byte_t* pbtInitData, const size_t szInitDataLen, tag_info* pti)
|
||||
* @fn nfc_initiator_select_tag(const nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t* pbtInitData, const size_t szInitDataLen, nfc_target_info_t* pti)
|
||||
* @brief Select a passive or emulated tag
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
* @param pdi dev_info struct pointer that represent currently used device
|
||||
* @param pnd nfc_device_t struct pointer that represent currently used device
|
||||
* @param im Desired modulation
|
||||
* @param pbtInitData Optional initiator data used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID.
|
||||
* @param szInitDataLen Length of initiator data \a pbtInitData.
|
||||
*
|
||||
* The NFC device will try to find the available passive tags. Some NFC devices are capable to emulate passive tags. The standards (ISO18092 and ECMA-340) describe the modulation that can be used for reader to passive communications. The chip needs to know with what kind of tag it is dealing with, therefore the initial modulation and speed (106, 212 or 424 kbps) should be supplied.
|
||||
* @note For every initial modulation type there is a different collection of information returned (in tag_info pointer pti) They all fit in the data-type which is called tag_info. This is a union which contains the tag information that belongs to the according initial modulation type.
|
||||
* @note For every initial modulation type there is a different collection of information returned (in nfc_target_info_t pointer pti) They all fit in the data-type which is called nfc_target_info_t. This is a union which contains the tag information that belongs to the according initial modulation type.
|
||||
*/
|
||||
bool nfc_initiator_select_tag(const dev_info* pdi, const init_modulation im, const byte_t* pbtInitData, const size_t szInitDataLen, tag_info* pti);
|
||||
bool nfc_initiator_select_tag(const nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t* pbtInitData, const size_t szInitDataLen, nfc_target_info_t* pti);
|
||||
|
||||
/**
|
||||
* @fn nfc_initiator_select_dep_target(const dev_info *pdi, const init_modulation im, const byte_t *pbtPidData, const size_t szPidDataLen, const byte_t *pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, tag_info * pti);
|
||||
* @fn nfc_initiator_select_dep_target(const nfc_device_t *pnd, const nfc_modulation_t nmInitModulation, const byte_t *pbtPidData, const size_t szPidDataLen, const byte_t *pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, nfc_target_info_t * pti);
|
||||
* @brief Select a target and request active or passive mode for DEP (Data Exchange Protocol)
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
* @param pdi dev_info struct pointer that represent currently used device
|
||||
* @param im Desired modulation (IM_ACTIVE_DEP or IM_PASSIVE_DEP for active, respectively passive mode)
|
||||
* @param pbtPidData passive initiator data, 4 or 5 bytes long, (optional, only for IM_PASSIVE_DEP, can be NULL)
|
||||
* @param pnd nfc_device_t struct pointer that represent currently used device
|
||||
* @param im Desired modulation (NM_ACTIVE_DEP or NM_PASSIVE_DEP for active, respectively passive mode)
|
||||
* @param pbtPidData passive initiator data, 4 or 5 bytes long, (optional, only for NM_PASSIVE_DEP, can be NULL)
|
||||
* @param pbtNFCID3i the NFCID3, 10 bytes long, of the initiator (optional, can be NULL)
|
||||
* @param pbtGbData generic data of the initiator, max 48 bytes long, (optional, can be NULL)
|
||||
*
|
||||
* The NFC device will try to find the available target. The standards (ISO18092 and ECMA-340) describe the modulation that can be used for reader to passive communications.
|
||||
* @note tag_info_dep will be returned when the target was acquired successfully.
|
||||
* @note nfc_target_info_t_dep will be returned when the target was acquired successfully.
|
||||
*/
|
||||
bool nfc_initiator_select_dep_target(const dev_info* pdi, const init_modulation im, const byte_t* pbtPidData, const size_t szPidDataLen, const byte_t* pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, tag_info* pti);
|
||||
bool nfc_initiator_select_dep_target(const nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t* pbtPidData, const size_t szPidDataLen, const byte_t* pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, nfc_target_info_t* pti);
|
||||
/**
|
||||
* @fn nfc_initiator_deselect_tag(const dev_info* pdi);
|
||||
* @fn nfc_initiator_deselect_tag(const nfc_device_t* pnd);
|
||||
* @brief Deselect a selected passive or emulated tag
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
* @param pdi dev_info struct pointer that represent currently used device
|
||||
* @param pnd nfc_device_t struct pointer that represent currently used device
|
||||
*
|
||||
* After selecting and communicating with a passive tag, this function could be used to deactivate and release the tag. This is very useful when there are multiple tags available in the field. It is possible to use the nfc_initiator_select_tag() function to select the first available tag, test it for the available features and support, deselect it and skip to the next tag until the correct tag is found.
|
||||
*/
|
||||
bool nfc_initiator_deselect_tag(const dev_info* pdi);
|
||||
bool nfc_initiator_deselect_tag(const nfc_device_t* pnd);
|
||||
|
||||
/**
|
||||
* @fn nfc_initiator_transceive_bits(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
|
||||
* @fn nfc_initiator_transceive_bits(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
|
||||
* @brief Transceive raw bit-frames
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
* @param pbtTx contains a byte array of the frame that needs to be transmitted.
|
||||
|
@ -136,29 +145,29 @@ bool nfc_initiator_deselect_tag(const dev_info* pdi);
|
|||
*
|
||||
* The NFC reader will transmit low-level messages where only the modulation is handled by the PN53X chip. Construction of the frame (data, CRC and parity) is completely done by libnfc. This can be very useful for testing purposes. Some protocols (e.g. MIFARE Classic) require to violate the ISO14443-A standard by sending incorrect parity and CRC bytes. Using this feature you are able to simulate these frames.
|
||||
*/
|
||||
bool nfc_initiator_transceive_bits(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar);
|
||||
bool nfc_initiator_transceive_bits(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar);
|
||||
|
||||
/**
|
||||
* @fn nfc_initiator_transceive_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
* @fn nfc_initiator_transceive_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
* @brief Transceive byte and APDU frames
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
*
|
||||
* The reader will transmit the supplied bytes in pbtTx to the target (tag). It waits for the response and stores the received bytes in the pbtRx byte array. The parity bits are handled by the PN53X chip. The CRC can be generated automatically or handled manually. Using this function, frames can be communicated very fast via the NFC reader to the tag. Tests show that on average this way of communicating is much faster than using the regular driver/middle-ware (often supplied by manufacturers).
|
||||
* @warning The configuration option DCO_HANDLE_PARITY must be set to true (the default value).
|
||||
* @warning The configuration option NDO_HANDLE_PARITY must be set to true (the default value).
|
||||
*/
|
||||
bool nfc_initiator_transceive_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool nfc_initiator_transceive_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
||||
/**
|
||||
* @fn nfc_initiator_transceive_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
* @fn nfc_initiator_transceive_dep_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
* @brief Transceive data
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
*
|
||||
* The reader will transmit the supplied (data) bytes in pbtTx to the target (tag). It waits for the response and stores the received bytes in the pbtRx byte array. The difference between this function and nfc_initiator_transceive_bytes is that here pbtTx and pbtRx contain *only* the data sent and received and not any additional commands, that is all handled internally by the PN53X.
|
||||
*/
|
||||
bool nfc_initiator_transceive_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool nfc_initiator_transceive_dep_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
||||
/**
|
||||
* @fn nfc_initiator_mifare_cmd(const dev_info* pdi, const mifare_cmd mc, const uint8_t ui8Block, mifare_param* pmp)
|
||||
* @fn nfc_initiator_mifare_cmd(const nfc_device_t* pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param* pmp)
|
||||
* @brief Execute a MIFARE Classic Command
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
* @param pmp Some commands need additional information. This information should be supplied in the mifare_param union.
|
||||
|
@ -168,10 +177,10 @@ bool nfc_initiator_transceive_dep_bytes(const dev_info* pdi, const byte_t* pbtTx
|
|||
*
|
||||
* First an authentication must take place using Key A or B. It requires a 48 bit Key (6 bytes) and the UID. They are both used to initialize the internal cipher-state of the PN53X chip (http://libnfc.org/hardware/pn53x-chip). After a successful authentication it will be possible to execute other commands (e.g. Read/Write). The MIFARE Classic Specification (http://www.nxp.com/acrobat/other/identification/M001053_MF1ICS50_rev5_3.pdf) explains more about this process.
|
||||
*/
|
||||
bool nfc_initiator_mifare_cmd(const dev_info* pdi, const mifare_cmd mc, const uint8_t ui8Block, mifare_param* pmp);
|
||||
bool nfc_initiator_mifare_cmd(const nfc_device_t* pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param* pmp);
|
||||
|
||||
/**
|
||||
* @fn nfc_target_init(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxBits)
|
||||
* @fn nfc_target_init(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits)
|
||||
* @brief Initialize NFC device as an emulated tag
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
*
|
||||
|
@ -179,61 +188,61 @@ bool nfc_initiator_mifare_cmd(const dev_info* pdi, const mifare_cmd mc, const ui
|
|||
*
|
||||
* @warning Be aware that this function will wait (hang) until a command is received that is not part of the anti-collision. The RATS command for example would wake up the emulator. After this is received, the send and receive functions can be used.
|
||||
*/
|
||||
bool nfc_target_init(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxBits);
|
||||
bool nfc_target_init(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits);
|
||||
|
||||
/**
|
||||
* @fn nfc_target_receive_bits(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
|
||||
* @fn nfc_target_receive_bits(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
|
||||
* @brief Receive bit-frames
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
*
|
||||
* This function makes it possible to receive (raw) bit-frames. It returns all the messages that are stored in the FIFO buffer of the PN53X chip. It does not require to send any frame and thereby could be used to snoop frames that are transmitted by a nearby reader. Check out the DCO_ACCEPT_MULTIPLE_FRAMES configuration option to avoid losing transmitted frames.
|
||||
* This function makes it possible to receive (raw) bit-frames. It returns all the messages that are stored in the FIFO buffer of the PN53X chip. It does not require to send any frame and thereby could be used to snoop frames that are transmitted by a nearby reader. Check out the NDO_ACCEPT_MULTIPLE_FRAMES configuration option to avoid losing transmitted frames.
|
||||
*/
|
||||
bool nfc_target_receive_bits(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar);
|
||||
bool nfc_target_receive_bits(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar);
|
||||
|
||||
/**
|
||||
* @fn nfc_target_receive_bytes(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxLen)
|
||||
* @fn nfc_target_receive_bytes(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
||||
* @brief Receive bytes and APDU frames
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
*
|
||||
* The main receive function that returns the received frames from a nearby reader.
|
||||
*/
|
||||
bool nfc_target_receive_bytes(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool nfc_target_receive_bytes(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
||||
/**
|
||||
* @fn nfc_target_receive_dep_bytes(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxLen)
|
||||
* @fn nfc_target_receive_dep_bytes(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
||||
* @brief Receive data
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
*
|
||||
* The main receive function that returns the received data from a nearby reader. The difference between this function and nfc_target_receive_bytes is that here pbtRx contains *only* the data received and not any additional commands, that is all handled internally by the PN53X.
|
||||
*/
|
||||
bool nfc_target_receive_dep_bytes(const dev_info* pdi, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool nfc_target_receive_dep_bytes(const nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen);
|
||||
|
||||
/**
|
||||
* @fn nfc_target_send_bits(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar)
|
||||
* @fn nfc_target_send_bits(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar)
|
||||
* @brief Send raw bit-frames
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
*
|
||||
* This function can be used to transmit (raw) bit-frames to the reader.
|
||||
*/
|
||||
bool nfc_target_send_bits(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar);
|
||||
bool nfc_target_send_bits(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar);
|
||||
|
||||
/**
|
||||
* @fn nfc_target_send_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen)
|
||||
* @fn nfc_target_send_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
||||
* @brief Send bytes and APDU frames
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
*
|
||||
* To communicate byte frames and APDU responses to the reader, this function could be used.
|
||||
*/
|
||||
bool nfc_target_send_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen);
|
||||
bool nfc_target_send_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen);
|
||||
|
||||
/**
|
||||
* @fn nfc_target_send_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen)
|
||||
* @fn nfc_target_send_dep_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
||||
* @brief Send data
|
||||
* @return Returns true if action was successfully performed; otherwise returns false.
|
||||
*
|
||||
* To communicate data to the reader, this function could be used. The difference between this function and nfc_target_send_bytes is that here pbtTx contains *only* the data sent and not any additional commands, that is all handled internally by the PN53X.
|
||||
*/
|
||||
bool nfc_target_send_dep_bytes(const dev_info* pdi, const byte_t* pbtTx, const size_t szTxLen);
|
||||
bool nfc_target_send_dep_bytes(const nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen);
|
||||
|
||||
/**
|
||||
* @fn const char* nfc_version(void)
|
||||
|
|
Loading…
Reference in a new issue