Compare commits

..

No commits in common. "master" and "libnfc-1.4.0" have entirely different histories.

250 changed files with 12288 additions and 31977 deletions

64
.gitignore vendored
View File

@ -1,64 +0,0 @@
**/.deps/
**/.libs/
**/Makefile
**/Makefile.in
*.exe
*.la
*.lo
*.o
*~
.vs/
CMakeSettings.json
Doxyfile
INSTALL
aclocal.m4
ar-lib
autom4te.cache/
build
compile
config.guess
config.h
config.h.in
config.log
config.status
config.sub
configure
debian/
depcomp
examples/nfc-anticol
examples/nfc-dep-initiator
examples/nfc-dep-target
examples/nfc-emulate-forum-tag2
examples/nfc-emulate-tag
examples/nfc-emulate-uid
examples/nfc-mfsetuid
examples/nfc-poll
examples/nfc-relay
examples/pn53x-diagnose
examples/pn53x-sam
examples/pn53x-tamashell
examples/quick_start_example1
examples/quick_start_example2
install-sh
libnfc.pc
libtool
ltmain.sh
m4/libtool.m4
m4/ltoptions.m4
m4/ltsugar.m4
m4/ltversion.m4
m4/lt~obsolete.m4
missing
stamp-h1
test-driver
test/run-test.sh.log
test/run-test.sh.trs
test/test-suite.log
utils/nfc-emulate-forum-tag4
utils/nfc-jewel
utils/nfc-list
utils/nfc-mfclassic
utils/nfc-mfultralight
utils/nfc-read-forum-tag3
utils/nfc-relay-picc
utils/nfc-scan-device

View File

@ -1,81 +0,0 @@
language: c
matrix:
include:
- os: windows
compiler:
- clang
before_install:
- mkdir build && cd build && wget "https://sourceforge.net/projects/libusb-win32/files/libusb-win32-releases/1.2.6.0/libusb-win32-bin-1.2.6.0.zip" && 7z x libusb-win32-bin-1.2.6.0.zip -o"$PROGRAMFILES" && mv "$PROGRAMFILES/libusb-win32-bin-1.2.6.0" "$PROGRAMFILES/libusb-win32"
install:
choco install doxygen.install ninja
script:
cmake -GNinja .. && cmake --build .
- os: linux
dist: bionic
compiler:
- clang
addons:
apt:
packages:
- libusb-dev
- doxygen
- cmake
script:
- mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=~/.local .. && make -j2 && make install
- os: linux
dist: bionic
compiler:
- clang
addons:
apt:
packages:
- libusb-dev
- doxygen
script:
- autoreconf -vfi && mkdir build && cd build && ../configure --prefix=$HOME/.local/ && make -j2 && make install
- os: linux
dist: bionic
compiler:
- gcc
addons:
apt:
packages:
- libusb-dev
- doxygen
- cmake
script:
- mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=~/.local .. && make -j2 && make install
- os: linux
dist: bionic
compiler:
- gcc
addons:
apt:
packages:
- libusb-dev
- doxygen
script:
- autoreconf -vfi && mkdir build && cd build && ../configure --prefix=$HOME/.local/ && make -j2 && make install
- os: osx
osx_image: xcode12
compiler:
- clang
before_install:
- brew install doxygen libusb-compat
script:
- mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=~/.local .. && make -j2 && make install
- os: osx
osx_image: xcode12
compiler:
- clang
before_install:
- brew install doxygen libusb-compat m4
script:
- autoreconf -vfi && mkdir build && cd build && ../configure --prefix=$HOME/.local/ && make -j2 && make install

47
AUTHORS
View File

@ -1,49 +1,2 @@
# Alphabetical cleaned output of "git shortlog -s -e|cut -c 8-" :
Adam Laurie <adam@algroup.co.uk>
Ahti Legonkov <ahti.legonkov@gmail.com>
Alex Lian <alian@alum.mit.edu>
Alexander Inyukhin <shurick@sectorb.msk.ru>
Anugrah Redja Kusuma <anugrah.redja@gmail.com>
Audrey Diacre <adiacre@il4p.fr>
Boris Moiseev <cyberbobs@gmail.com>
Christoph Gritschenberger <christoph.gritschenberger@gmail.com>
Dario Carluccio <dario.carluccio@gmail.com>
David Kreitschmann <david@kreitschmann.de>
Emanuele Bertoldi <emanuele.bertoldi@gmail.com>
Emmanuel Dreyfus <manu@netbsd.org>
Eugeny Boger <eugenyboger@gmail.com>
Francois Kooman <fkooman@tuxed.net>
Frank Morgner <frankmorgner@gmail.com>
Frédéric Bourgeois <bourgeoislab@gmail.com>
Hidde Wieringa <hidde@hiddewieringa.nl>
Jairo Andres Suarez <andres4005@gmail.com>
Jiapeng Li <gapleehit@gmail.com>
Jim Anastassiou <jim.anastassiou@gmail.com>
John Galt <centromere@users.noreply.github.com>
Julien Ehrhart <julien.ehrhart@live.com>
Julien Schueller <julien.schueller@gmail.com>
Laurent Latil <laurent@latil.nom.fr>
Ludovic Rousseau <ludovic.rousseau@gmail.com>
Marcello Morena <marcello.morena@gmail.com>
Marcos Vives Del Sol <socram8888@gmail.com>
Mati Vait <mativait@gmail.com>
Maxim Martyanov <llorephie@gmail.com>
Mike Auty <mike.auty@gmail.com>
Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Olliver Schinagl <oliver@schinagl.nl>
Paul Menzel <paul.menzel@giantmonkey.de>
Peter Meerwald <pmeerw@pmeerw.net>
Philippe Teuwen <yobibe@gmail.com>
Pim 't Hart <pimmeyproductions@gmail.com>
Ray Lee <rayleesky@outlook.com>
Roel Verdult <roel@libnfc.org> Roel Verdult <roel@libnfc.org>
Romain Tartiere <romain.tartiere@gmail.com>
Romuald Conty <romuald@libnfc.org> Romuald Conty <romuald@libnfc.org>
Simon Yorkston <simon.yorkston@gmail.com>
bhack <s.fabri@email.it>
lego <lego@debian-fresh.prx>
quantum-x <simon.yorkston@gmail.com>
timzi <developers@make-gadget.ru>
xantares <xantares09@hotmail.com>
xaqq <kapp.arno@gmail.com>
yerzhanm <yerzhan.mukhamejan@gmail.com>

116
CMake-Windows.txt Normal file
View File

@ -0,0 +1,116 @@
Requirements - Running
======================
In order to use the library and run included examples, at least this
dependency should be installed:
- Microsoft Visual C++ 2008 SP1 Redistributable Package [1]
These C++ 2008 SP1 libraries are also part of "Microsoft .NET Framework 3.5
Service Pack 1 and .NET Framework 3.5 Family" which can be obtained through
Windows Update.
There are two versions of the redistributable package (one for x86 and one for
x64). Be sure which one is needed.
An optional requirement is:
- LibUsb-Win32 0.1.12.2 [2]
In case support for the PN531USB and PN533USB is needed. LibUsb has serious issues
on Windows systems newer than Windows XP (and on 64 bit). See LibUsb support
mailing lists for more information.
Requirements - Development
==========================
This project uses CMake for creating a Visual Studio project from the
source files.
The following software was used to create the libnfc distribution:
- CMake 2.6.4 [3]
- Microsoft Windows SDK for Windows 7 (7.0) [4]
- Microsoft .NET framework 3.5 SP1 (Windows Update)
- LibUsb-Win32 0.1.12.2 (only on Windows XP builds) [2]
- NSIS 2.45 (to create the installer) [5]
- 7-Zip 4.65 (for generating source archive) [6]
This was tested on Windows XP SP3, but should work on Windows Vista and
Windows 7 as well. Even on 64 bit systems.
Building
========
To build the distribution the NMake Makefiles generator of CMake was used. Here
is an example of how to generate a distribution with the above mentioned
requirements fulfilled (it is assumed the CMake binaries are in the system
path, this is optional during installation of CMake):
- Start -> Programs -> Microsoft Windows SDK v7.0 -> CMD shell
- Now it is possible to run CMake and NMake:
C:\Program Files\Microsoft SDKs\Windows\v7.0> cd c:\dev\libnfc-read-only
C:\dev\libnfc-read-only> mkdir bin
C:\dev\libnfc-read-only> cd bin
C:\dev\libnfc-read-only\bin> cmake-gui ..
Now you can configure the build. Press "Configure", specify "NMake Makefiles"
and then you have the opportunity to set some configuration variables. If you
don't want a Debug build change the variable CMAKE_BUILD_TYPE to "Release".
If a non-GUI solution is preferred one can use:
C:\dev\libnfc-read-only\bin> cmake -G "NMake Makefiles"
-DCMAKE_BUILD_TYPE=Release ..
Now run NMake:
C:\dev\libnfc-read-only\bin> nmake package
To create the binary package, or:
C:\dev\libnfc-read-only\bin> nmake package_source
To create the source archive.
NMake will create a shared library for Windows (nfc.dll), and
a library file (nfc.lib) to link your applications against. It will compile
the tools against this shared library. The installer will install the
DLL file in the same directory as the tools as our goal was to be able to
run and install libnfc as a standard user. In a system wide installation
the DLL should be placed in "windows\system32" or any other directory in
the (system) path.
If you want your own tools to use libnfc you have to link them with "nfc.lib"
which can be found in the "lib" directory under the installation root. The
header files can be found under "include" in the installation root.
In a "normal" Windows install this would be:
- "C:\Program Files\libnfc-x.x.x\lib"
- "C:\Program Files\libnfc-x.x.x\include"
You also need to copy the "nfc.dll" file to the same directory as your
application, or install it somewhere in the system path (see above).
CMake can also be used to create the MSVC [7] project files instead of NMake
Makefiles, after which MSVC can be used to compile the project, create an
installer, etc.
Building 64 Bit
===============
Building on native 64 bit should work "out of the box".
It is also possible to "cross compile" for 64 bit systems on a 32 bit system.
This can be accomplished by using the "setenv" command from the shell opened
in the previous section. Try "setenv /?" to see what is available. When cross
compiling the name of the binary installer package generated is not correct,
because CMake does not notice it is cross compiling. It should work fine
however.
References
==========
[1] http://www.microsoft.com/downloads/details.aspx?familyid=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2
[2] http://libusb-win32.sourceforge.net/
[3] http://www.cmake.org
[4] http://msdn.microsoft.com/en-us/windows/bb980924.aspx
[5] http://nsis.sourceforge.net/Main_Page
[6] http://http://www.7-zip.org/
[7] http://www.microsoft.com/express/vc/

View File

@ -1,13 +1,7 @@
cmake_minimum_required (VERSION 2.6) PROJECT(libnfc C)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
if (NOT DEFINED CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE Release CACHE STRING "Build type")
endif ()
project (libnfc C)
SET(VERSION_MAJOR "1") SET(VERSION_MAJOR "1")
SET(VERSION_MINOR "8") SET(VERSION_MINOR "4")
SET(VERSION_PATCH "0") SET(VERSION_PATCH "0")
SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
@ -17,58 +11,28 @@ SET(PACKAGE_VERSION ${VERSION})
SET(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") SET(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
# config.h # config.h
IF(WIN32) IF(NOT WIN32)
SET(LIBNFC_SYSCONFDIR "./config" CACHE PATH "libnfc configuration directory")
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/cmake/config_windows.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/contrib/win32)
IF(NOT MINGW)
SET(CMAKE_C_FLAGS "-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE ${CMAKE_C_FLAGS}")
ENDIF(NOT MINGW)
ELSE(WIN32)
SET(_XOPEN_SOURCE 600) SET(_XOPEN_SOURCE 600)
SET(SYSCONFDIR "/etc" CACHE PATH "System configuration directory") ENDIF(NOT WIN32)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/cmake/config_posix.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
ENDIF(WIN32)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_SOURCE_DIR}/config.h)
ADD_DEFINITIONS("-DHAVE_CONFIG_H") ADD_DEFINITIONS("-DHAVE_CONFIG_H")
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include)
# Win32
IF(WIN32)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/contrib/win32 ${CMAKE_CURRENT_SOURCE_DIR}/contrib/win32/stdint)
ENDIF(WIN32)
# make it easy to locate CMake modules for finding libraries # make it easy to locate CMake modules for finding libraries
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/modules/") SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules/")
# Options # Options
option (LIBNFC_LOG "Enable log facility (errors, warning, info and debug messages)" ON) SET(LIBNFC_DEBUG_OUTPUT OFF CACHE BOOL "Debug output of communication with the NFC chip")
IF(LIBNFC_LOG) IF(LIBNFC_DEBUG_OUTPUT)
ADD_DEFINITIONS(-DLOG) ADD_DEFINITIONS(-DDEBUG -g3)
ENDIF(LIBNFC_LOG) ENDIF(LIBNFC_DEBUG_OUTPUT)
option (LIBNFC_ENVVARS "Enable envvars facility" ON)
IF(LIBNFC_ENVVARS)
ADD_DEFINITIONS(-DENVVARS)
ENDIF(LIBNFC_ENVVARS)
SET(LIBNFC_DEBUG_MODE OFF CACHE BOOL "Debug mode")
IF(LIBNFC_DEBUG_MODE)
ADD_DEFINITIONS(-DDEBUG)
SET(CMAKE_C_FLAGS "-g3 ${CMAKE_C_FLAGS}")
SET(WIN32_MODE "debug")
SET(CMAKE_RC_FLAGS "-D_DEBUG ${CMAKE_RC_FLAGS}")
ELSE(LIBNFC_DEBUG_MODE)
SET(WIN32_MODE "release")
ENDIF(LIBNFC_DEBUG_MODE)
option (LIBNFC_CONFFILES_MODE "Enable configuration files" ON)
IF(LIBNFC_CONFFILES_MODE)
ADD_DEFINITIONS(-DCONFFILES)
ENDIF(LIBNFC_CONFFILES_MODE)
option (BUILD_EXAMPLES "build examples ON/OFF" ON)
option (BUILD_UTILS "build utils ON/OFF" ON)
option (BUILD_DEBPKG "build debian package ON/OFF" OFF)
# Doxygen # Doxygen
SET(builddir "${CMAKE_BINARY_DIR}") SET(builddir "${CMAKE_BINARY_DIR}")
@ -94,212 +58,46 @@ IF(NOT DEFINED SHARE_INSTALL_PREFIX)
ENDIF(NOT DEFINED SHARE_INSTALL_PREFIX) ENDIF(NOT DEFINED SHARE_INSTALL_PREFIX)
# Additonnal GCC flags # Additonnal GCC flags
IF(CMAKE_COMPILER_IS_GNUCC) IF(CMAKE_COMPILER_IS_GNU_CC)
# Make sure we will not miss some warnings ;) # Make sure we will not miss some warnings ;)
SET(CMAKE_C_FLAGS "-Wall -pedantic -std=c99 ${CMAKE_C_FLAGS}") ADD_DEFINITIONS(-Wall -pedantic -std=c99)
ENDIF(CMAKE_COMPILER_IS_GNUCC) ENDIF(CMAKE_COMPILER_IS_GNU_CC)
# Workarounds for libusb in C99 # Workarounds for libusb in C99
ADD_DEFINITIONS(-Du_int8_t=uint8_t -Du_int16_t=uint16_t) ADD_DEFINITIONS(-Du_int8_t=uint8_t -Du_int16_t=uint16_t)
IF(MINGW)
IF (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
# force MinGW-w64 in 32bit mode
SET(CMAKE_C_FLAGS "-m32 ${CMAKE_C_FLAGS}")
SET(CMAKE_MODULE_LINKER_FLAGS "-m32 -Wl,--enable-stdcall-fixup ${CMAKE_SHARED_LINKER_FLAGS}")
SET(CMAKE_SHARED_LINKER_FLAGS "-m32 -Wl,--enable-stdcall-fixup ${CMAKE_SHARED_LINKER_FLAGS}")
SET(CMAKE_EXE_LINKER_FLAGS "-m32 -Wl,--enable-stdcall-fixup ${CMAKE_EXE_LINKER_FLAGS}")
SET(CMAKE_RC_FLAGS "--target=pe-i386 --output-format=coff ${CMAKE_RC_FLAGS}")
ELSE(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86")
# force MinGW-w64 in 32bit mode
MESSAGE("Building 32-bit Windows DLL")
#SET(CMAKE_C_FLAGS "-m32 ${CMAKE_C_FLAGS}")
#SET(CMAKE_MODULE_LINKER_FLAGS "--Wl,--enable-stdcall-fixup ${CMAKE_SHARED_LINKER_FLAGS}")
#SET(CMAKE_SHARED_LINKER_FLAGS "--Wl,--enable-stdcall-fixup ${CMAKE_SHARED_LINKER_FLAGS}")
#SET(CMAKE_EXE_LINKER_FLAGS "--Wl,--enable-stdcall-fixup ${CMAKE_EXE_LINKER_FLAGS}")
SET(CMAKE_RC_FLAGS "--target=pe-i386 --output-format=coff ${CMAKE_RC_FLAGS}")
ELSEIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
MESSAGE("Building 64-bit Windows DLL")
SET(CMAKE_RC_FLAGS "--target=pe-x86-64 --output-format=coff ${CMAKE_RC_FLAGS}")
ELSE(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86")
MESSAGE(FATAL_ERROR "Unknown Processor: ${CMAKE_SYSTEM_PROCESSOR}")
ENDIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86")
ENDIF(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
FIND_PROGRAM(DLLTOOL dlltool CMAKE_FIND_ROOT_PATH_BOTH)
IF (NOT DLLTOOL)
MESSAGE(FATAL_ERROR "Could not find dlltool command")
ENDIF (NOT DLLTOOL)
ENDIF(MINGW)
IF(NOT WIN32) IF(NOT WIN32)
# Set some pkg-config variables # Set some pkg-config variables
SET(prefix ${CMAKE_INSTALL_PREFIX}) SET(prefix ${CMAKE_INSTALL_PREFIX})
SET(exec_prefix ${CMAKE_INSTALL_PREFIX}) SET(exec_prefix ${CMAKE_INSTALL_PREFIX})
SET(PACKAGE "libnfc") SET(PACKAGE "libnfc")
IF(LIBNFC_DRIVER_PN53X_USB) IF(LIBNFC_DRIVER_PN531_USB OR LIBNFC_DRIVER_PN533_USB)
SET(PKG_REQ ${PKG_REQ} "libusb") SET(PKG_REQ ${PKG_REQ} "libusb")
ENDIF(LIBNFC_DRIVER_PN53X_USB) ENDIF(LIBNFC_DRIVER_PN531_USB OR LIBNFC_DRIVER_PN533_USB)
IF(LIBNFC_DRIVER_ACR122_USB) IF(LIBNFC_DRIVER_ACR122)
SET(PKG_REQ ${PKG_REQ} "libusb")
ENDIF(LIBNFC_DRIVER_ACR122_USB)
IF(LIBNFC_DRIVER_PCSC)
SET(PKG_REQ ${PKG_REQ} "libpcsclite") SET(PKG_REQ ${PKG_REQ} "libpcsclite")
ENDIF(LIBNFC_DRIVER_PCSC) ENDIF(LIBNFC_DRIVER_ACR122)
IF(LIBNFC_DRIVER_ACR122_PCSC)
SET(PKG_REQ ${PKG_REQ} "libpcsclite")
ENDIF(LIBNFC_DRIVER_ACR122_PCSC)
# CMake lists are separated by a semi colon, replace with colon # CMake lists are separated by a semi colon, replace with colon
STRING(REPLACE ";" "," PKG_CONFIG_REQUIRES "${PKG_REQ}") STRING(REPLACE ";" "," PKG_CONFIG_REQUIRES "${PKG_REQ}")
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libnfc.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libnfc.pc @ONLY) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libnfc.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libnfc.pc @ONLY)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libnfc.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libnfc.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
ENDIF(NOT WIN32) ENDIF(NOT WIN32)
INCLUDE(LibnfcDrivers)
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
IF(I2C_REQUIRED)
# Inspired from http://cmake.3232098.n2.nabble.com/RFC-cmake-analog-to-AC-SEARCH-LIBS-td7585423.html
INCLUDE (CheckFunctionExists)
INCLUDE (CheckLibraryExists)
CHECK_FUNCTION_EXISTS (clock_gettime HAVE_CLOCK_GETTIME)
IF (NOT HAVE_CLOCK_GETTIME)
CHECK_LIBRARY_EXISTS (rt clock_gettime "" HAVE_CLOCK_GETTIME_IN_RT)
IF (HAVE_CLOCK_GETTIME_IN_RT)
SET(LIBRT_FOUND TRUE)
SET(LIBRT_LIBRARIES "rt")
ENDIF (HAVE_CLOCK_GETTIME_IN_RT)
ENDIF (NOT HAVE_CLOCK_GETTIME)
ENDIF(I2C_REQUIRED)
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
IF(PCSC_INCLUDE_DIRS)
INCLUDE_DIRECTORIES(${PCSC_INCLUDE_DIRS})
LINK_DIRECTORIES(${PCSC_LIBRARY_DIRS})
ENDIF(PCSC_INCLUDE_DIRS)
IF(LIBUSB_INCLUDE_DIRS)
INCLUDE_DIRECTORIES(${LIBUSB_INCLUDE_DIRS})
LINK_DIRECTORIES(${LIBUSB_LIBRARY_DIRS})
SET(LIBUSB_FOUND TRUE)
ENDIF(LIBUSB_INCLUDE_DIRS)
# version.rc for Windows
IF(WIN32)
# Date for filling in rc file information
IF (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
MACRO (GET_CURRENT_YEAR RESULT)
EXECUTE_PROCESS(COMMAND "cmd" " /C date /T" OUTPUT_VARIABLE ${RESULT})
STRING(REGEX REPLACE "\n" "" ${RESULT} ${${RESULT}})
STRING(REGEX REPLACE ".*(..)/(..)/(....).*" "\\3" ${RESULT} ${${RESULT}})
ENDMACRO (GET_CURRENT_YEAR)
ELSE(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
MACRO (GET_CURRENT_YEAR RESULT)
EXECUTE_PROCESS(COMMAND "date" "+%Y" OUTPUT_VARIABLE ${RESULT})
STRING(REGEX REPLACE "\n" "" ${RESULT} ${${RESULT}})
ENDMACRO (GET_CURRENT_YEAR)
ENDIF(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
GET_CURRENT_YEAR(CURRENT_YEAR)
MESSAGE("Year for copyright is " ${CURRENT_YEAR})
SET(prefix ${CMAKE_INSTALL_PREFIX})
SET(RC_COMMENT "${PACKAGE_NAME} library")
SET(RC_INTERNAL_NAME "${PACKAGE_NAME} ${WIN32_MODE}")
SET(RC_ORIGINAL_NAME ${PACKAGE_NAME}.dll)
# RC_FILE_TYPE: VFT_DLL
SET(RC_FILE_TYPE 0x00000002L)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/contrib/win32/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/windows/libnfc.rc @ONLY)
ENDIF(WIN32)
ADD_SUBDIRECTORY(libnfc) ADD_SUBDIRECTORY(libnfc)
ADD_SUBDIRECTORY(include) ADD_SUBDIRECTORY(include)
ADD_SUBDIRECTORY(examples)
if (BUILD_UTILS)
add_subdirectory (utils)
endif ()
if (BUILD_EXAMPLES)
add_subdirectory (examples)
endif ()
if (NOT MSVC)
# config script install path
if ( NOT DEFINED LIBNFC_CMAKE_CONFIG_DIR )
set ( LIBNFC_CMAKE_CONFIG_DIR lib${LIB_SUFFIX}/cmake/libnfc )
endif ()
set ( LIBNFC_INCLUDE_DIR ${includedir} )
set ( LIBNFC_INCLUDE_DIRS ${LIBNFC_INCLUDE_DIR} )
list ( APPEND LIBNFC_INCLUDE_DIRS ${LIBUSB_INCLUDE_DIRS} )
set ( LIBNFC_LIBRARY nfc )
set ( LIBNFC_LIBRARIES ${LIBNFC_LIBRARY} )
list ( APPEND LIBNFC_LIBRARIES ${LIBUSB_LIBRARIES} )
set ( LIBNFC_LIBRARY_DIRS ${libdir} )
set ( LIBNFC_ROOT_DIR ${prefix} )
set ( LIBNFC_VERSION_STRING ${VERSION} )
set ( LIBNFC_VERSION_MAJOR ${VERSION_MAJOR} )
set ( LIBNFC_VERSION_MINOR ${VERSION_MINOR} )
set ( LIBNFC_VERSION_PATCH ${VERSION_PATCH} )
set ( LIBNFC_USE_FILE ${CMAKE_INSTALL_PREFIX}/${LIBNFC_CMAKE_CONFIG_DIR}/UseLibNFC.cmake )
if(CMAKE_VERSION VERSION_LESS 2.8.8)
configure_file ( cmake/LibNFCConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/LibNFCConfig.cmake @ONLY )
configure_file ( cmake/LibNFCConfigVersion.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/LibNFCConfigVersion.cmake @ONLY )
else ()
include(CMakePackageConfigHelpers)
configure_package_config_file (
cmake/LibNFCConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/LibNFCConfig.cmake
INSTALL_DESTINATION ${LIBNFC_CMAKE_CONFIG_DIR}
PATH_VARS
LIBNFC_USE_FILE
LIBNFC_ROOT_DIR
LIBNFC_INCLUDE_DIR
LIBNFC_INCLUDE_DIRS
LIBNFC_LIBRARY_DIRS
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
write_basic_package_version_file (
LibNFCConfigVersion.cmake
VERSION ${LIBNFC_VERSION_STRING}
COMPATIBILITY AnyNewerVersion
)
endif ()
install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/LibNFCConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/LibNFCConfigVersion.cmake
cmake/UseLibNFC.cmake
DESTINATION ${LIBNFC_CMAKE_CONFIG_DIR}
)
endif ()
# Binary Package # Binary Package
IF(WIN32) IF(WIN32)
SET(CPACK_GENERATOR "ZIP") SET(CPACK_GENERATOR "NSIS")
ELSE(WIN32) ELSE(WIN32)
SET(CPACK_GENERATOR "TBZ2") SET(CPACK_GENERATOR "TBZ2")
IF(BUILD_DEBPKG)
SET(CPACK_GENERATOR "DEB")
ENDIF(BUILD_DEBPKG)
ENDIF(WIN32) ENDIF(WIN32)
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Near Field Communication (NFC) library") SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Near Field Communication (NFC) library")
SET(CPACK_PACKAGE_VENDOR "Roel Verdult") SET(CPACK_PACKAGE_VENDOR "Roel Verdult")
SET(CPACK_PACKAGE_CONTACT "Roel Verdult <roel@libnfc.org>") SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
#Readme file
IF(WIN32)
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README-Windows.md")
ELSE(WIN32)
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
ENDIF(WIN32)
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "libnfc") SET(CPACK_PACKAGE_INSTALL_DIRECTORY "libnfc")
SET(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) SET(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
SET(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR}) SET(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
@ -324,5 +122,5 @@ ELSE(WIN32)
ENDIF(WIN32) ENDIF(WIN32)
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "libnfc-${VERSION}") SET(CPACK_SOURCE_PACKAGE_FILE_NAME "libnfc-${VERSION}")
SET(CPACK_SOURCE_IGNORE_FILES "~$" "/\\\\.git/" "bin/") SET(CPACK_SOURCE_IGNORE_FILES "~$" "/\\\\.svn/" "bin/")
INCLUDE(CPack) INCLUDE(CPack)

569
ChangeLog
View File

@ -1,569 +1,3 @@
May 22, 2020 - 1.8.0
--------------------
Fixes:
- Restore nfc_modulation_type enum order to keep compatibility with libnfc 1.7.1
Changes:
- Bump revision due to changes in API introduced in v1.7.2
- Bump library version to 6.0.0
May 21, 2020 - 1.7.2 (avoid using it, incompatible with 1.7.1)
--------------------
Fixes:
- Remove unreachable code
- nfc_emulate_uid: cleaner exit on interrupt
- Fix reporting of modulations and baud rates by nfc-scan-device -v
- Fix out-of-bounds access in nfc-mfultralight
- Several Cygwin compilation fixes
- Fix comparison when nfc_initiator_target_is_present() with a specified target
- Fix nfc_initiator_poll_target without tag on PN532
- Export iso14443b* symbols
- Fix udev rule which was executed too early
- Fix improper device name initialization
- Fix setenv()/unsetenv() for Windows
- Fix win32/nfc.def according to nfc.h
- Fix missing timeout in pn53x_initiator_select_passive_target()
- nfc-mfclassic: fix option to tolerate write errors
- nfc-poll: fix card removing check
- nfc-relay-picc: fix wrong open mode for file descriptor
Improvements:
- Allow ISO14443A to be used at higher baud rates
- nfc_initiator_select_passive_target() now checks against
reported modulations and baud rates for current device
- More serial devices on MAC OS X
- Add section to README to help to configure libnfc
- Various cmake improvements
- Drop PCRE dependency on Windows
- Remove deprecated readdir_r
- Markdown conversion of the text files
- Use hardcoded PN533 descriptors to be more robust on Windows
- Add support for SCL3712
- Add support for ACR1222U-C1
- Add support for NetBSD
- Add support for PN532 on RPi3 UART
- Add support for cross-compilation of 32b & 64b versions of the library for Windows
- Add pn533_usb to the kernel modules blacklist
- Add support for pn71xx NXP's NFC Controllers through Linux Libnfc-nci (untested)
- Add support for contactless PC/SC readers (only as initiator)
- Add support for Feitian R502 and bR500 into pcsc driver
- Add support for HID iClass (Picopass) support (nfc-iclass tool in external nfc-tools repo)
- Allows for sending empty data in nfc_initiator_transceive_bits
- driver i2c: respect proper timing specifications
- driver i2c: add retry on error mechanism
- nfc-mfclassic: improvements fo magic cards
- nfc-mfclassic: add option to specify UID
- nfc-mfclassic/nfc-mfsetuid: add support for new gen (1b) of magic 4K cards
- nfc-mfclassic: Add RATS support indicator
- nfc-mfsetuid: allow to write complete Block0, instead of only UID
- nfc-mfultralight: add automatic modes and --check-magic
- nfc-mfultralight: add support for magic gen2 cards
- nfc-mfultralight: add option to specify UID
- nfc-mfultralight: add support for Ultralight NTAG213/215/216
- nfc-barcode: new command to read and decode NFC Barcodes (Tag-Talks-First)
Changes:
- nfc_device_get_supported_baud_rate() takes now a "mode" parameter
- New nfc_device_get_supported_baud_rate_target_mode()
- New NFC modulation type NMT_BARCODE and nfc_barcode_info struct to support Thinfilm NFC Barcode protocol
- New NFC modulation type NMT_ISO14443BICLASS and NMT_ISO14443BICLASS struct to support HID iClass (Picopass)
- pn53x_transceive() is now part of public API
Special thanks to:
- Jim Anastassiou, Frédéric Bourgeois, Dario Carluccio, Emmanuel Dreyfus,
Julien Ehrhart, S. Fabri, John Galt, Christoph Gritschenberger,
Alexander Inyukhin, Arnaud Kapp, David Kreitschmann, Adam Laurie, Ray Lee,
Maxim Martyanov, Paul Menzel, Boris Moiseev, Yerzhan Mukhamejan,
Olliver Shinagl, Jairo Andres Suarez, Mati Vait, Marcos Vives Del Sol,
Hidde Wieringa, Simon Yorkston, timzi, usk-johnny-s, xantares, Hanno
Heinrichs, jgeslin, Mikolaj Stawiski, rstular, Khem Raj, Frank Morgner, jpwidera,
Feitian Technologies
Feb 24, 2014 - 1.7.1
--------------------
Fixes:
- Fix several issues reported by Coverity Scan
(mem leaks, buff overflows, reuse after free, etc)
- More robust when several conflicting uart drivers are in the config
- Fix racing condition with uart_flush_input()
- Silent pn53x_check_communication error messages when scanning
- Fix nfc_target_init(), was returning success in case of timeout
- Windows: fix several compilation issues
- On tag selection, save current target info also for ISO14443B*
- nfc-read-forum-tag3: fix incomplete NDEF retrieval and size of output file
Improvements:
- nfc-list: New option to choose which technologies to poll for
- UART: drivers now supported under kFreeBSD
- New LIBNFC_DEVICE env var to use one reader and exclude all other readers
while LIBNFC_DEFAULT_DEVICE only prepends it to the configured devices list
- New LIBNFC_AUTO_SCAN env var to enable(default)/disable auto scan
- On tag selection, save current target info even if pnt=NULL
- On tag selection, grant NP_INFINITE_SELECT also for ISO14443B*
- Save & restore NP_INFINITE_SELECT status when changing it internally
- nfc-mfclassic: add format/wipe command (thanks to Adam Laurie)
- nfc-jewel: new utility to read/write Topaz/Jewel tags (thanks to Pim 't Hart)
- nfc_initiator_select_passive_target() provides defaults if pbtInitData=NULL
- nfc-read-forum-tag3: add -q option, add full parsing of NDEF Attribute Block
Fixes & improvements specific to nfc_initiator_target_is_present():
- Supports fully PN532 & PN533, not tested on other chips
- Fix usage after nfc_initiator_poll_target()
- Set correctly last_error
- Fix issue when there was no saved target
- Allow NULL pointer to tag
- Fix issues in case of tear off conditions
- Now works with:
* MFUL, MFC, MFC Mini, MFC 7-byte (re-selection: you'll need to auth again)
* ISO14443-4A, ISO14443-4B
* ISO14443-4B', ASK CTx, ST SRx
* Jewel
* FeliCa
Sep 03, 2013 - 1.7.0
--------------------
Fixes:
- pn53x: only create a current target when at least one have been found
- pn532_uart: fix 'operation abort' feature with this driver
- pn532_uart: let more time to PN532 to wake-up, this fix some specific cases
where PN532 shown one of two runs (Thanks to Marcello Morena)
- nfc-mfclassic: allow option f for read operation too
- Avoid clash with system's htole32 if it exists
- Include <stdlib.h>, required for getenv(3)
- usb: fix USB enumeration issue (Thanks to Mike Auty)
- acr122_pcsc: fix compilation on Mac OSX 10.8.4
- Fix pn53x_initiator_transceive_bytes_timed() measures for TypeB
- Various minor fixes: warnings, style, etc.
Improvements:
- New PN532 over I2C driver, see contrib/libnfc/pn532_i2c_on_rpi.conf.sample
- ACR122/Touchatag: misc improvements
- ReadMobib/ReadNavigo: improve shell script portability
- Add ISO14443-4 chaining support for RX (MI)
- UART: add support for BeagleBone serial ports (Thanks to Johan Henselmans)
- nfc-mfultralight: allow setting of UID for special 'chinese' ultralight cards
Special thanks to:
- Laurent Latil (new pn532_i2c driver for linux)
- Nobuhiro Iwamatsu (warning fixes and debian package)
Apr 05, 2013 - 1.7.0-rc7 (release candidate)
--------------------------------------------
Fixes:
- Fix bug when compiling without libusb
- Fix several memory leaks in error handling conditions
- Remove calls to exit() from the library
- Create safer snprint_nfc_*() instead of sprint_nfc_*() functions
- Fix warnings returned by cppcheck & clang/scan-build
- Obsolete function 'usleep' => nanosleep()
- Non reentrant function 'readdir' => readdir_r()
- Non reentrant function 'strtok' => new connstring_decode()
- Buffer may not be null-terminated after call to strncpy()
- scanf without field width limits can crash with huge input data
- Resource leaks: missing fclose()
- Dead code, unused vars & vars scopes warnings
- Unify copyright notices & update authors lists
- Windows: Fix compilation due to new usbbus file
- Windows: Clean up compiler/linker warnings
- Fixed the suppression of the auto-fixup for linking against MS built libs
- Fixed all the formatting warnings by shifting to inttypes.h specifiers
- shifted to %lu for DWORD printf
- nfc-anticol: fix ATS length
- nfc-mfclassic: fix reporting of processed blocks total
- nfc-mfclassic: detect MIFARE Plus 2K as 2K instead of 1K
- pn53x_usb/acr122_usb: check usb_open() returns before using it
Improvements:
- New PN532 over SPI driver, see contrib/libnfc/pn532_spi_on_rpi.conf.sample
- Devels HACKING file: introduce clang/scan-build & cppcheck for better code
- Better internal dependencies handling (bus <> drivers)
- Cleaner handling of portability patches
- Windows: logging via OutputDebugString(), ease debugging
- nfc-mfclassic: use smaller files for cards < 4k
- nfc-mfclassic: by defaut don't authorise wrong keyfile, use "f" to force
- quick_start_example1.c: remove err.h dependency, easier for Windowsians
- nfc-mfclassic: support some new magic cards with writeable sector #0
- nfc-anticol: add -t option to use timed functions
Changes:
- Upon malloc error, nfc_init() doesn't force exit() anymore
so now you should test if context != NULL after nfc_init() call
- API: nfc_initiator_target_is_present() & str_nfc_target()
now take a pointer to nfc_target as argument instead of passing by value
Special thanks to:
- Eugeny Boger (new pn532_spi driver for linux)
Mar 03, 2013 - 1.7.0-rc6 (release candidate)
--------------------------------------------
Fixes:
- Fix several memory leaks (nfc_drivers, libusb, config parser)
- Fix stack smash while displaying long data transmission (LOG_HEX)
- pn53x-tamashell: allow larger commands up to full extended frame
- Add missing windows file in archive (version.rc.in)
- Fix compilation warnings & potential bugs
- Fix documentation
- Fix missing malloc() calls checks
- Fix missing free() calls in some error handlers
Improvements:
- Allow to disable conffils & envvar supports on embedded platforms
- Add option to nfc-mfclassic to tolerate RW errors
Changes:
- Replace usb_set_debug() in applications by LIBNFC_LOG_LEVEL libusb group
Feb 16, 2013 - 1.7.0-rc5 (release candidate)
--------------------------------------------
Fixes:
- Add missing sample configuration file in archive
- Add missing windows files in archive
- Preserve error code while using pn53x_set_property_bool() with
NP_AUTO_ISO14443_4 flag
Improvements:
- New nfc_register_driver() function allowing to hook custom drivers
- New nfc_free() function to free allocated buffers
Special thanks to:
- Ahti Legonkov (new nfc_register_driver())
Feb 04, 2013 - 1.7.0-rc4 (release candidate)
--------------------------------------------
Fixes:
- Fix tag selection for nfc-mfclassic, nfc-mfultralight, nfc-read-forum-tag3
and nfc-relay-picc
- Fix crash in nfc-relay-picc -i/-t if fd3 or fd4 is missing
Improvements:
- Windows support build with CMake
Changes:
- Configuration directory (ie. libnfc.conf) can now be set a compile-time
- Log can be enabled/disabled using CMake
Special thanks to:
- Alex Lian (Windows support improvements)
- Nobuhiro Iwamatsu (Debian package improvements)
Jan 31, 2013 - 1.7.0-rc3 (release candidate)
--------------------------------------------
Fixes:
- Fix pn53x_usb bulk write timeout
- Fix BCC in nfc-emulate-uid example
- Fix nfc-relay-picc example
- Fix a miss returned value within some internal functions (user program could
be affected)
- Fix nfc-scan-device -i option
- Remove wrong exit() calls in library
- Fix issue in driver acr122_usb affecting Touchatag
- Reenable some idle in all drivers, add selectively PowerDown when possible
Changes:
- nfc_emulate_target() now takes timeout parameter
Special thanks to:
- Alex Lian (Windows support refresh)
Jan 20, 2013 - 1.7.0-rc2 (release candidate)
--------------------------------------------
Fixes:
- Fix API version in debian files
- Fix wrong condition to display a warning when user disables autoscan
- Fix unit tests
- Fix ISO14443B' ATS
Improvements:
- Allow device.optional=true to tolerate missing device
Changes:
- pn532_uart driver is now enabled by default
Dec 09, 2012 - 1.7.0-rc1 (release candidate)
--------------------------------------------
Fixes:
- nfc_initiator_deselect_target() now returns 0 on success (as expected by caller)
- example/pn532-sam: Fix few bugs
- Fix ACR122S device detection when no ACR122S device available (endless UART receive)
- Suppress a lot of compiler warnings !.. which fixes many potential bugs
- Display right driver name while detecting PCSC
- Correctly handle PCSC header files on Mac OS X
- Fix nfc-emulation (now works with utils/nfc-emulate-forum-tag4 and Nexus S)
Improvements:
- New nfc_initiator_init_secure_element() function to set SAM as wired card (only relevant with a PN532 SAM-equipped)
- New str_nfc_target(), str_nfc_modulation_type(), str_nfc_baud_rate() function to convert some libnfc's types into allocated string
- New nfc_device_target_is_present() to check if passed target is in the field
- --enable-serial-autoprobe option at compile time to replace it with some run-time options
- New -i option to nfc-scan-device to allow intrusive scan
- New feature, libnfc now uses configuration files:
* main configuration file can be used to set options (ie. intrusive, autoscan, log-level)
* main configuration file can contains a device as default device, HIGHLY recommended for UART devices users
* multiple devices files can be used to declare multiple devices and ordered them
- UART port scan now includes ttyAMA* to detect UART-devices connected on Raspberry Pi (e.g. `nfc-scan-device -i`)
- Support for OpenPCD2 (with a dedicated firmware)
- Support for FTDI dongle under MacOS
- Enhance messages display
- Provides modprobe configuration file and instructions for Linux >3.1 with PN533 users.
- Greatly improve log facility with log level filter, configurable using conf file (ie. /etc/nfc/libnfc.conf) or environment var LIBNFC_LOG_LEVEL
- New man page for nfc-read-forum-tag3 utility (Thanks to UNFORGiVEN512)
- New man page for nfc-scan-device utility
- New man page for nfc-emulate-forum-tag2 example
- README: Add few words about device permissions and udev/devd rules available in package
- utils/nfc-emulate-forum-tag4: add support for v2.0 of the spec
- New "make style" command to have a beautiful code
- Code cleanup (indentation, white spaces, etc.)
Changes:
- New nfc_device_get_information_about() now allocates returned string
- No more in/out paramaters in nfc_initiator_transceive_*() functions
- Rename nfc-probe to nfc-scan-device
- Rename abtUid from struct mifare_param_auth into abtAuthUid: this is not the UID while using 7-bytes UID MIFARE Classic tags.
- utils/nfc-list: always display the card type when a card is found
- nfc-utils: new fingerprinting method closer to AN10833, (Thanks to Balazs Bucsay)
See NEWS file for major changes (ie. API changes)
Special thanks to:
- Ludovic Rousseau (Code cleanup, tests under MacOS, etc.)
- Frank Morgner
Feb 27, 2012 - 1.6.0-rc1 (release candidate)
--------------------------------------------
Fixes:
- utils/nfc-mfclassic: use MIFARE instead of Mifare typo
- utils/nfc-list: continue to attempt to reach devices after a connection failure
- libnfc: avoid readline auto-detection when cross-compiling
- driver/pn53x_usb: fix path usage for FreeBSD
- doc: quick_start_example1.c fixed
- utils/*: verbose option back for nfc-list, and newly implemented in nfc-poll
Improvements:
- libnfc: enhanced documentation
- libnfc: debug facility back without external depends
- libnfc: add nfc_device_get_supported_modulation() and nfc_device_get_supported_baud_rate() functions
- libnfc: enhanced code indent
- drivers: implement driver for ACR122S device
- utils/nfc-mfclassic: remove non-conscistent "extract payload" option in nfc-mfclassic
- utils/nfc-emulate-forum-tag2: add missing manpage
- utils/nfc-read-forum-tag3: add missing manpage
- tests/*: fix some warnings in test
- tests/test_dep*: add some DEP tests (Active/Passive in several baud rates)
- doc: quick_start_example1 is now compiled when running make check or distcheck
- libnfc: a printf-based logging replaces log4c
- libnfc: various minor fixes/enhancements
- utils/*: nfc-probe example added to show devices connection strings
Changes:
- PN53x specific errors are not public anymore;
- Timeouts are now integers instead of timeval structure
- Removes libusb types workaround (r200) as it seems to not be needed anymore but may disturb compiler
- Removes parse_args() from nfc-utils.[hc]
- Move nfc-emulate-forum-tag2 from utils to examples.
- contrib: move udev and devd files into contrib/
- debian: udev rules file renamed
See NEWS file for major changes (ie. API changes)
Special thanks to:
- Thomas Hood (Debian packages and various fixes/contributions)
- Anugrah Redja (ACR122S driver)
Oct 17, 2011 - 1.5.1 (unstable)
-------------------------------
Fixes:
- libnfc: fix invalid memory access when a new driver is probing for hardware and the number of requested devices was already reached
- chips/pn53x: fix bug in _timed fcts
- drivers/pn53x_usb: fix crash when usb_bulk_read() fails.
- drivers/pn53x_usb: continue to search a available device on usb errors (ie. Device Busy)
- drivers/pn53x_usb: make PN53x usb connection more stable
- examples/nfc-relay: fix UID problem
- windows: fix uart_receive() under Win32 platform
Improvements:
- libnfc: add logging facility using log4c.
- libnfc: abort mecanism is now implemented in driver layer, so it can use pipe-based mecanism (as PN532_UART or ARYGON driver does under POSIX system) or flag-based mecanism.
- libnfc: add ISO/IEC 14443 B' aka Type B' modulation partial support
- libnfc: add partial support (list) for ISO14443B-3 ST SRx & ASK CTx cards
- libnfc: compile unit tests only on demand unless using --enable-debug.
- libnfc: error handling improvements
- libnfc: new function nfc_idle() to set the NFC device in idle mode
- libnfc: add partial support for Sony S360 reader
- libnfc: some manual test reports have been added
- libnfc: list_targets support for ASK CTS512B (no anticol support yet)
- libnfc: nfc_disconnect() now switches NFC device into idle before disconnecting
- libnfc: nfc_initiator_poll_target() is now available for all devices
- libnfc: implement software polling for non-PN532 equipped device
- chips/pn53x: add pn53x_data_new() function to alloc and init pn53x_data structure
- chips/pn53x: add some SFR registers description
- chips/pn53x: implement WriteBack cache
- chips/pn53x: new pn53x_PowerDown wrapper for PowerDown (PN532) command
- chips/pn53x: prints a debug trace when reading PN53x registers
- chips/pn53x: set some parameters in ISO/IEC 14443A when using DEP mode (ie. SAK says ISO/IEC 18092 compliant) (Android NFC stack now detects the target as DEP)
- chips/pn53x: some optimisations in registers initialisation
- chips/pn53x: list_passive_targets() fixed for TypeB on LoGO
- chips/pn53x: pn53x_data now have a operating_mode enum to know the current running mode (initiator, target or idle)
- drivers/*: all commands are now abortable
- drivers/pn532_uart,arygon: make valgrind happy with UART-based drivers
- drivers/pn53x*: use shared pn53x_ack_frame[] and pn53x_nack_frame[] instead of local declaration
- drivers/pn53x_usb: all USB errors are now reported in text format
- drivers/pn53x_usb: enable progressive field on init to allow pn53x-tamashell to works (note: it does not distrib progressive field enabling when nfc_list_passive_target() is used)
- drivers/pn53x_usb: implement PN53x extended information frames with USB devices
- drivers/pn53x_usb: use progressive field on/off only for ISO14443 Type B target listing
- buses/uart: now provides an abort mecanism for windows users
- buses/uart: UART based drivers could now use uart_flush_input() to discard junk bytes on input.
- examples/nfc-anticol: add -f option to force RATS
- examples/nfc-mfclassic: handle 7-byte UID cards & MFC Mini
- examples/nfc-anticol: now use nfc_abort_command()
- examples/nfc-dep-*: disconnect from NFC device on error.
- examples/nfc-emulate-forum-tag2: add new example to emulate a NFC Forum Tag Type 2
- examples/nfc-emulate-forum-tag4: add document references.
- examples/nfc-emulate-forum-tag4: this example now fails with ENOTSUPP when used with a non-PN532 chip.
- examples/nfc-mfclassic: write special Mifare 1K cards, including Block 0 / UID
- examples/nfc-mfsetuid: add a new example to set UID of special Mifare 1K cards
- examples/nfc-read-forum-tag3: add new example to read a NFC Forum Tag Type 3
- examples/pn53x-tamashell-scripts: minor enhancements
- tests/test-dep: add a threaded DEP test to check DEP communication between two local devices
- debian: enable all drivers at compile time
- debian: improve debian packaging (Thanks to Thomas Hood)
- debian: use a numbering that allow to have libnfc pre-version and debian package pre-version too. (Thanks to Thomas Hood)
- freebsd: add FreeBSD devd(8) snippet configuration for Sony S330 readers.
- windows: implement abort mecanism in pn532_uart driver (Based on provided patch: many thanks to Edwin Evans)
- windows: USB drivers now relies on libusb-win32 with version >= 1.2.4.x (1.2.4.6 recommended) (Many thanks to Glenn)
- windows: implement automatic uart port detection and input flush (Thanks to Edwin Evans)
Changes:
- libnfc: add 'struct timeval *timeout' parameter for pn53x_transceive(), pn53x_target_receive_bytes() and pn53x_target_send_bytes().
Apr 29, 2011 - 1.5.0 (unstable)
-------------------------------
Fixes:
- libnfc: silent warnings with more strict CFLAGS
- libnfc: update devd(8) rules file for FreeBSD
- libnfc: make libnfc compile under Windows
- libnfc: fix nfc_pick_device() when called from nfc_connect with NULL nfc_device_desc_t parameter
- chips/pn53x: fix a bug when value is larger than mask when using WriteRegister
- chips/pn53x: adapt MaxRetries to avoid issue with 2 tags on PN531
- examples/nfc-mfclassic: UID was shown reverse-ordered
Improvements:
- libnfc: use a new way to handle drivers, introduce a real HAL
- libnfc: use absolute include path instead of relative ones
- libnfc: move some nfc_device_t members in a better place
- libnfc: improve nfc_driver_t struct to embedded HAL API
- libnfc: nfc_device_t now embeddeds driver data and chip data pointers (useful to be more generic)
- libnfc: use more readable variables instead of strange coding convention
- libnfc: move PRINT_HEX macro into nfc-internal.h
- libnfc: introduce an abort mecanism
- libnfc: suppress any PN53x references in nfc.c
- libnfc: nfc-mfclassic and nfc-mfcultralight examples are now compiled under Windows
- chips/pn53x: use the powerful C99 writing to construct PN53x commands
- chips/pn53x: remove almost all memcpy()
- chips/pn53x: WriteRegister, ReadRegister and SetParameters command wrappers are correctly named
- chips/pn53x: introduce chip state (SLEEP, NORMAL or EXECUTE)
- chips/pn53x: add SAMConfiguration command wrapper (need to be improved)
- chips/pn53x: remove almost all const arrays
- chips/pn53x: use human readable defines for commands instead of hex values
- chips/pn53x: in debug mode, the PN53x command is shown in human-readable string, awesome isn't it? ;-)
- chips/pn53x: try to determine IC version instead of hardcode it.
- chips/pn53x: new fonction to build frames instead of build them in each driver
- chips/pn53x: enable aborting blocking commands (e.g. TgInitAsTarget) and refactor *_check_communication() as pn53x_check_communication().
- chips/pn53x: add timed versions of transceive_bytes/bits, allow to detect emulated/non-emulated tags and more...
- chips/pn53x: support CRC auto-handling in ...transceive_bytes_timed
- drivers/pn53x_usb: ASK LoGO: enable progressive field feature.
- drivers/pn532_uart: major improvement of UART handling
- drivers/pn532_uart: check PN53x frames when received
- drivers/pn53x_usb: enhance ASK LoGO dedicated code
- drivers/pn53x_usb: add LEDs support for ASK LoGO and SCL3711
- drivers/pn532_uart: implement extended frame send/receive for PN532_UART driver.
- drivers/arygon: use the new way to drive UART (its far more stable)
- drivers/arygon: do not hard code PN532 chip type: pn53x_init() determine it and ARYGON device seems to not need to be waken up.
- drivers/arygon: reject too heavy payload (ARYGON does not support PN53x extended frame even with PN532 equipped device)
- drivers/pn532_uart & arygon: now runs almost twice faster than the previous stable release
- buses/uart: receive() is now based on expected bytes instead of calculated timeouts..
- buses/uart: simplify uart_send() on POSIX systems.
- examples/nfc-emulate-tag: minor comments improvements.
- examples: remove nfc-message.h usage from examples.
- examples/nfc-emulate-forum-tag4: fully reworked example: it now support all NFC-Forum device in read and write mode
- examples/pn53x-tamashell: add an example for LoGO LEDs
- examples/pn53x-tamashell: add a script to read Mobib card.
- examples/pn53x-tamashell: add a script to read Navigo card.
Changes:
- libnfc: merge macros from nfc-messages.h into nfc-internal.h
- libnfc: remove useless files: nfc-messages.h, buses.h and chips.h
- API: new nfc_emulate_target() that ease target emulation for developer
- macros: show PRINT_HEX result on stderr in debug mode (that helps to sync with debug msg which are printed on standard error output.)
- drivers: split transceive() into send() and receive() to be able to handle more cases (differed replies, abort commands, etc) later
- drivers: use a const structure of functions instead of -dirty- callbacks array
- drivers/pn53x_usb: pn531_usb and pn533_usb drivers are now merged and use the pn53x IC version autodetection
- buses/uart: use a smart way to determine available ports on POSIX systems (tested on Linux and FreeBSD)
Feb 21, 2011 - 1.4.2
--------------------
Fixes:
- libnfc: fgets instead of getline, bring MacOSX / BSD without glibc alive
- libnfc: add missing CMake files to generated tarball needed by windows users (Thanks to Glenn)
- drivers/pn532_uart: fix pn532 wakeup response handling
- buses/uart: prevent from retrieving more than buffer length (potential buffer overflow)
- buses/uart: intent to speed up interface
- nfc-emulate-uid: use a correct UID
- nfc-mfclassic: fixes a segfault when using only 1 argument
Improvements:
- libnfc: silent some compilation warnings
- drivers/pn533_usb: support new device: ASK / LoGO. (Thanks to ASK for sending one sample)
- chips/pn53x: set register directly if mask cover whole value.
- pn53x-tamashell: accepts script as arg, this makes shebang possible
- pn53x-tamashell: add pause command & doc
- documentation: add a README-Windows.txt file
- documentation: add more pcsc-lite related instruction in README
Feb 1, 2011 - 1.4.1
-------------------
Fixes:
- libnfc: fix missing pn53x-tamashell-scripts in generated tarball. (Thanks to usermeister)
- buses/uart: improved UART communication on POSIX systems: slower devices can be detected and high speed devices works better
- buses/uart: serial autoprobe now skips invalid devices but checks all ports in the list
- drivers/pn53x_usb: prevent from stack corruption when using PN533-based device and add errors handling for ReadRegister and WriteRegister
- drivers/arygon: fix polling on ARYGON devices
- examples/nfc-emulate-tag: switch off easy framing when we are not emulating a ISO14443-4 target
- examples/nfc-mfclassic: fix crash when file cannot be opened for writing
- examples/nfc-mfultralight: fix 7 bytes UID display
Improvements:
- libnfc: add a "troubleshooting" section in README to document ACR122 problems with pcsclite.
- libnfc: inform user if target UID can not be emulated
- example/nfc-mfultralight: handle lock page writing
- examples/nfc-emulate-tag: handle HALT & READ
- tests: add register access test
Experimental: Windows platform support (Thanks to Glenn Ergeerts)
Nov 17, 2010 - 1.4.0 Nov 17, 2010 - 1.4.0
-------------------- --------------------
@ -617,7 +51,6 @@ Changes:
- examples: change examples license for the sake of consistency: LGPL covers library, re-usable examples code is now under BSD license. - examples: change examples license for the sake of consistency: LGPL covers library, re-usable examples code is now under BSD license.
Aug 31, 2010 - 1.3.9 Aug 31, 2010 - 1.3.9
-------------------- --------------------
@ -723,7 +156,7 @@ Fixes:
- libnfc: Fix tag re-selection with UID length > 4 bytes (like DESFire or Ultralight); - libnfc: Fix tag re-selection with UID length > 4 bytes (like DESFire or Ultralight);
- nfc-mfclassic: Fix authenticated only with KEYA; - nfc-mfclassic: Fix authenticated only with KEYA;
Improvements: Improvments:
- build: Build on FreeBSD; - build: Build on FreeBSD;
- build: Add alternative build system (CMake); - build: Add alternative build system (CMake);
- build: Add new files usefull for desktop GNU/Linux users: some rules for udev to allow non-root access to PN53x USB devices; - build: Add new files usefull for desktop GNU/Linux users: some rules for udev to allow non-root access to PN53x USB devices;

File diff suppressed because it is too large Load Diff

View File

@ -1,68 +0,0 @@
Hello hackers!
General remarks about contributing
----------------------------------
Contributions to the libnfc are welcome!
Here are some directions to get you started:
1. Follow style conventions
The source code of the library trend to follow some conventions so that it
is consistent in style and thus easier to read.
Look around and respect the same style.
Don't use tabs. Increment unit is two spaces.
Don't leave dandling spaces or tabs at EOL.
Helper script to get some uniformity in the style:
$ make style
If you use vim see the [Vim: How to prevent trailing whitespaces](http://www.carbon-project.org/Vim__How_to_prevent_trailing_whitespaces.html).
2. Chase warnings: no warning should be introduced by your changes
Depending what you touch, you can check with:
2.1 When using autotools
$ autoreconf -Wall -vis
2.2 When compiling
2.2.1 Using extra flags:
$ export CFLAGS="-Wall -g -O2 -Wextra -pipe -funsigned-char -fstrict-aliasing \
-Wchar-subscripts -Wundef -Wshadow -Wcast-align -Wwrite-strings -Wunused \
-Wuninitialized -Wpointer-arith -Wredundant-decls -Winline -Wformat \
-Wformat-security -Wswitch-enum -Winit-self -Wmissing-include-dirs \
-Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition \
-Wbad-function-cast -Wnested-externs -Wmissing-declarations"
$ ./configure
$ make clean
$ make
2.2.2 Using clang:
You can use same CFLAGS but also `-Wunreachable-code`
$ scan-build ./configure
$ make clean
$ scan-build make
2.2.3 Using `cppcheck` (v1.58 or higher):
$ make cppcheck
2.3 When Debianizing
$ lintian --info --display-info --display-experimental *deb
or (shorter version)
$ lintian -iIE *deb
3. Preserve cross-platform compatibility
The source code should remain compilable across various platforms,
including some you probably cannot test alone so keep it in mind.
Supported platforms:
- Linux
- FreeBSD
- Mac OS X
- Windows with MinGW

165
LICENSE Normal file
View File

@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -2,60 +2,52 @@ ACLOCAL_AMFLAGS = -I m4
AM_CFLAGS = $(LIBNFC_CFLAGS) AM_CFLAGS = $(LIBNFC_CFLAGS)
SUBDIRS = libnfc utils SUBDIRS = libnfc examples include cmake_modules test
if EXAMPLE_ENABLED
SUBDIRS += examples
endif
SUBDIRS += include contrib cmake test
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libnfc.pc pkgconfig_DATA = libnfc.pc
EXTRA_DIST = \ EXTRA_DIST = Doxyfile pn53x.conf pn53x.rules CMakeLists.txt config.h.cmake LICENSE
CMakeLists.txt \ CLEANFILES = Doxygen.log
Doxyfile \
HACKING.md \
NEWS.md \
README.md \
README-Windows.md \
libnfc.conf.sample \
mingw-cross-compile.sh
CLEANFILES = Doxygen.log coverage.info libnfc.pc if DOC_ENABLED
clean-local:
clean-local: clean-local-doc clean-local-coverage
.PHONY: clean-local-coverage clean-local-doc doc style
clean-local-coverage:
-rm -rf coverage
clean-local-doc:
rm -rf doc rm -rf doc
doc : Doxyfile doc : Doxyfile
@DOXYGEN@ $(builddir)/Doxyfile @DOXYGEN@ $(builddir)/Doxyfile
.PHONY: doc
endif
if HAS_INDENT
INDENT_ARGS = --blank-before-sizeof \
--blank-lines-after-commas \
--blank-lines-after-procedures \
--braces-after-func-def-line \
--braces-on-if-line \
--braces-on-struct-decl-line \
--continue-at-parentheses \
--cuddle-else \
--declaration-indentation 8 \
--indent-level 2 \
--line-length 120 \
--no-blank-lines-after-declarations \
--no-tabs \
--preprocessor-indentation 2 \
--procnames-start-lines \
--space-after-cast \
--space-after-procedure-calls
indent:
@[ ! -d $(top_srcdir)/.svn ] || \
[ 0 -eq $$(svn status | grep '\.[hc]$$' | tee /dev/fd/2 | wc -l) ] || \
( echo "These files are localy modified. 'commit' or 'reverse' them, then retry." >&2; false )
@for f in $$(find $(top_srcdir)/libnfc $(top_srcdir)/include $(top_srcdir)/examples -name "*.[hc]"); do \
echo " INDENT $$f"; \
$(INDENT) $(INDENT_ARGS) "$$f" || exit 1; \
done
endif
DISTCHECK_CONFIGURE_FLAGS="--with-drivers=all" DISTCHECK_CONFIGURE_FLAGS="--with-drivers=all"
style:
find . -name "*.[ch]" -exec perl -pi -e 's/[ \t]+$$//' {} \;
find . -name "*.[ch]" -exec astyle --formatted --mode=c --suffix=none \
--indent=spaces=2 --indent-switches --indent-preprocessor \
--keep-one-line-blocks --max-instatement-indent=60 \
--style=linux --pad-oper --unpad-paren --pad-header \
--align-pointer=name {} \;
cppcheck:
cppcheck --quiet \
-I include -I libnfc -I libnfc/buses -I libnfc/chips -I libnfc/drivers \
--check-config .
cppcheck --quiet --enable=all --std=posix --std=c99 \
-I include -I libnfc -I libnfc/buses -I libnfc/chips -I libnfc/drivers \
-DLOG -D__linux__ \
-DDRIVER_PN53X_USB_ENABLED -DDRIVER_ACR122_PCSC_ENABLED \
-DDRIVER_ACR122_USB_ENABLED -DDRIVER_ACR122S_ENABLED \
-DDRIVER_PN532_UART_ENABLED -DDRIVER_ARYGON_ENABLED \
-DDRIVER_PN532_SPI_ENABLED -DDRIVER_PN532_I2C_ENABLED \
--force --inconclusive .

161
NEWS Normal file
View File

@ -0,0 +1,161 @@
New in 1.4.0:
API Changes
* Types
- New nfc_device_option value (enum): NDO_FORCE_ISO14443_A to force the
chip to switch in ISO14443-A
- New nfc_dep_mode_t (enum) for DEP mode:
NDM_UNDEFINED, NDM_PASSIVE, NDM_ACTIVE
- New nfc_modulation_type_t (enum) that lists modulation types:
NMT_ISO14443A, NMT_ISO14443B, NMT_FELICA, NMT_JEWEL, NMT_DEP
- New nfc_baud_rate_t (enum): list of baud rates:
NBR_UNDEFINED, NBR_106, NBR_212, NBR_424, NBR_847
- nfc_target_type_t have been removed from API (use nfc_modulation_t
instead)
* Structures
- nfc_device_t now have a boolean bAutoIso14443_4 to keep the locally the
state of NDO_AUTO_ISO14443_4 (should not be directly set, use
nfc_configure() with NDO_AUTO_ISO14443_4)
- nfc_device_t now have an uint8_t ui8Parameters to cache PN53x parameters
- nfc_device_t now have a byte_t btSupportByte to cache supported
modulations
- nfc_dep_info_t have completely changed, please see API documentation
- nfc_iso14443b_info_t have completely changed, please see API
documentation
- nfc_modulation_t have completely changed: it now contains a
nfc_modulation_type_t and nfc_baud_rate_t couple. Initialization example:
nfc_modulation_t nm = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
- nfc_target_t now contains new nfc_modulation_t instead of
nfc_target_type_t. Initialization example:
nfc_target_t nt = {
.nm.nmt = NMT_ISO14443A,
.nm.nbr = NBR_UNDEFINED,
.nti.nai.abtAtqa = { 0x03, 0x44 },
.nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef },
.nti.nai.btSak = 0x20,
.nti.nai.szUidLen = 4,
.nti.nai.abtAts = { 0x75, 0x77, 0x81, 0x02, 0x80 },
.nti.nai.szAtsLen = 5,
};
* Functions
- nfc_initiator_select_passive_target() now use new nfc_modulation_t and
nfc_target_t instead of nfc_target_info_t
- nfc_initiator_list_passive_targets() now use new nfc_modulation_t and
nfc_target_t instead of nfc_target_info_t
- nfc_initiator_poll_targets() use new nfc_modulation_t instead of
nfc_target_type_t
- nfc_initiator_select_dep_target() completely changed, use now
nfc_dep_mode_t, nfc_baudrate_t, nfc_dep_info_t and nfc_target_t, please
see API documentation
- nfc_target_init() have an additional argument: nfc_target_t to describe
the wanted target
- append_iso14443a_crc() was renamed to iso14443a_crc_append()
- New iso14443a_locate_historical_bytes() to locate historical bytes in ATS
New in 1.3.9 (since 1.3.4):
Installed files
- mifaretag.h and mifareultag.h are removed, Mifare features are not a part
of libnfc API anymore (these features are always available in examples/)
API Changes
* Types
- New nfc_device_option_t value (enum): NDO_AUTO_14443_4, an option to
enable/disable auto-switching to ISO/IEC 14443-4 if device is compliliant
- New nfc_device_option_t value (enum): NDO_EASY_FRAMING, an option to
enable/disable automatic frames encapsulation and chaining
- New nfc_target_type_t (enum), with values like NTT_MIFARE,
NTT_ISO14443B_106, NTT_DEP_ACTIVE_424, etc.
- Mifare related types have been removed from API: mifare_cmd,
mifare_param_auth, mifare_param_data, mifare_param_value, mifare_param
* Structures
- nfc_device_t now have boolean bEasyFraming to enable/disable "easy
framing" feature (should not be directly set, use nfc_configure() with
NDO_EASY_FRAMING)
- nfc_device_t now have integer iLastError to handle last error
- New chip_callbacks to handle error lookup per chip
- driver_callbacks now have a pointer to chip_callbacks
- New nfc_target_t that contains nfc_target_info_t and nfc_target_type_t
* Functions
- nfc_initiator_select_tag() became nfc_initiator_select_passive_target()
- New nfc_initiator_list_passive_targets() returns a list of detected
target on desired modulation
- (experimental) New nfc_initiator_poll_targets() returns targets that are
detected during hardware polling (available only with PN532)
- nfc_initiator_transceive_dep_bytes(), nfc_target_receive_dep_bytes() and
nfc_target_send_dep_bytes() have been removed from API, use
NDO_EASY_FRAMING option to switch from raw mode to "easy framing"
- nfc_initiator_mifare_cmd() have been removed: no more Mifare related
stuff in libnfc's API
- New nfc_strerror(), nfc_strerror_r() and nfc_perror() to report errors
- New append_iso14443a_crc() to append iso14443a_crc() to a string
New in 1.3.4 (since 1.2.1):
Installed files
- Headers are now installed in include/nfc instead of include/libnfc
- libnfc.h have been renamed to nfc.h
- defines.h and types.h have been merge into nfc-types.h
- bitutils.h is not installed anymore, some functions are now in
examples/nfc-utils.c
- devices.h, dev_acr122.h, dev_arygon.h, dev_pn531.h, dev_pn533.h and rs232.h
are not installed anymore
- New header mifareultag.h, like mifaretag.h for Mifare UltraLight
- New header nfc-messages.h with messages macros (DBG, ERR, INFO)
API Changes
* Types
- uint32_t which was used as size now are size_t
- chip_type became nfc_chip_t (enum)
- init_modulation became nfc_modulation_t (enum), and now have
NM_ACTIVE_DEP and NM_PASSIVE_DEP modulation values added
* Structures
- dev_info became nfc_device_t
- dev_config_option became nfc_device_option_t
- New nfc_device_desc_t to describe the way to access to a NFC device.
Initialisation example:
nfc_device_desc_t ndd = {
ndd.pcDriver = "ARYGON";
ndd.pcPort = "/dev/ttyUSB0";
ndd.uiSpeed = 115200;
};
- dev_callbacks became driver_callbacks and now have two function pointers
more: pick_device() and list_devices()
- New nfc_dep_info_t to handle DEP targets info
- tag_info_iso14443a became nfc_iso14443a_info_t
- tag_info_iso14443b became nfc_iso14443b_info_t
- tag_info_felica became nfc_felica_info_t
- tag_info_jewel became nfc_jewel_info_t
- tag_info became nfc_target_info_t, and now have extended union to
nfc_dep_info_t
* Functions
- nfc_connect() now takes 1 nfc_devive_desc_t argument (can be NULL)
- New nfc_list_devices(), it find available NFC devices using all know
drivers
- (experimental) New nfc_initiator_select_dep(), it looks for DEP targets
- (experimental) New nfc_initiator_transceive_dep_bytes(), like
nfc_initiator_transceive_bytes() for DEP targets
- (experimental) New nfc_target_receive_dep_bytes() and
nfc_target_send_dep_bytes(), to receive/send bytes to DEP target
(configured as initiator) while local NFC device is configured as target
- New nfc_device_name() returns the device's name
- New iso14443a_crc() computes CRC as described in ISO/IEC 14443
- New nfc_version() returns the actual version of libnfc (with SVN
revision, if available)

394
NEWS.md
View File

@ -1,394 +0,0 @@
New in 1.8.0:
API Changes:
- Restore nfc_modulation_type enum order to keep compatibility with libnfc 1.7.1
- Bump library version to 6.0.0
New in 1.7.2:
Drivers:
* New driver for pn71xx NXP's NFC Controllers through Linux Libnfc-nci (untested)
* New driver for contactless PC/SC readers (only as initiator)
API Changes:
* nfc_device_get_supported_baud_rate() now takes also "mode" as argument
* New nfc_device_get_supported_baud_rate_target_mode()
* New NFC modulation type NMT_BARCODE and nfc_barcode_info struct to support Thinfilm NFC Barcode protocol
* New NFC modulation type NMT_ISO14443BICLASS and NMT_ISO14443BICLASS struct to support HID iClass (Picopass)
* pn53x_transceive() is now part of public API
New in 1.7.1:
API Changes:
* nfc_initiator_select_passive_target() provides defaults if pbtInitData=NULL
* nfc_initiator_target_is_present() allow NULL pointer to tag
New in 1.7.0:
Drivers:
* New PN532 over I2C driver, see contrib/libnfc/pn532_i2c_on_rpi.conf.sample
API Changes:
* New function iso14443b_crc_append()
New in 1.7.0-rc7:
Drivers:
* New PN532 over SPI driver, see contrib/libnfc/pn532_spi_on_rpi.conf.sample
API Changes:
* Functions
- nfc_initiator_target_is_present() & str_nfc_target():
now take a pointer to nfc_target as argument
- nfc_init(): upon malloc error, doesn't force exit() anymore
so now you should test if context != NULL after nfc_init() call
New in 1.7.0-rc5:
API Changes:
* Functions
- New nfc_register_driver() function allowing to hook custom drivers.
New in 1.7.0-rc3:
API Changes:
* Functions
- Add timeout param to nfc_emulate_target()
New in 1.7.0-rc2:
Configuration:
libnfc can now use a configuration file for special setups, or features
activation. This file (/etc/nfc/libnfc.conf under GNU/Linux systems)
supports already some keywords:
- "allow_autoscan" to enable/disable device auto-detection feature;
- "allow_intrusive_scan" to enable/disable intrusive auto-detection
(ie. serial port probing);
- "log_level" to select library verbosity;
- "device.name" and "device.connstring" to define a user device,
this is the recommended method if user has a not easily detectable
device (ie. a serial one).
It is also possible to define devices using dedicated configuration files and
put them into device search directory (/etc/nfc/devices.d under GNU/Linux).
Example for the OpenPCD2: create /etc/nfc/devices.d/openpcd2.conf with:
name = "OpenPCD2"
connstring = "pn532_uart:/dev/ttyACM0"
optional = true
The keyword "optional" does not mandate the device to be present always
(it detects if the reader is indeed present before using it)
API Changes:
* Types
- New NFC_ESOFT error to handle software errors (allocations, pipe
creation, etc.)
* Functions
- Remove nfc_get_default_device() function: the default device is now the
first in nfc_list_devices() or could be open using NULL connstring with
nfc_open() function.
- New enum-to-string converter functions str_nfc_modulation_type() and
str_nfc_baud_rate()
- New str_nfc_target() to convert nfc_target struct into allocated string
- New nfc_device_get_information_about() function to retreive some device's
information
- No more in/out function parameter: nfc_initiator_transceive_*() now
take a constant size for Rx buffer
- New nfc_initiator_target_is_present() to test is the previously selected
target is available in the field
- nfc_initiator_transceive_bytes() returns NFC_EMFCAUTHFAIL when AUTH
command failed on a Mifare Classic
- New nfc_initiator_init_secure_element() to initiate a connection with
secure element (Only supported with a PN532 with SAM equipped)
New in 1.6.0-rc1:
API Changes:
* Types
- '_t' suffix removed from all types (e.g. nfc_device_t is now nfc_device)
- All errors removed in flavour of NFC_EIO, NFC_EINVARG, NFC_EDEVNOTSUPP,
NFC_ENOTSUCHDEV, NFC_EOVFLOW, NFC_ETIMEOUT, NFC_EOPABORTED, NFC_ENOTIMPL,
NFC_ETGRELEASED, NFC_ERFTRANS, NFC_ECHIP and NFC_SUCCESS
- nfc_device_desc_t replaced by nfc_connstring: libnfc now uses connection
strings to describe a device
- byte_t typedef removed, libnfc now uses uint8_t from C99
- nfc_device is now an opaque type
- nfc_properties replaces nfc_options
* Functions
- New nfc_get_default_device() function that allows to grab the connstring
stored in LIBNFC_DEFAULT_DEVICE environnement variable or returns the
first available device if not set
- New nfc_device_get_connstring() accessor function to know the device
connstring
- New nfc_device_set_property_bool() function that replace nfc_configure()
- New nfc_device_set_property_int() function to set integer property
- nfc_device_name() renamed to nfc_device_get_name() for the sake of
consistency
- New nfc_device_get_last_error() function, an accessor to last error occured
- Whole libnfc's functions now return 0 (NFC_SUCCESS) or positive value if
appropriated on success and libnfc's error code on failure
- nfc_connect(), nfc_disconnect() renamed to nfc_open(), nfc_close()
respectively
- Add 2 new functions: initialization and deinitialization functions:
nfc_init() and nfc_exit()
- New nfc_device_get_supported_modulation() and
nfc_device_get_supported_baud_rate() functions
* Dependencies
- log4c is not anymore used for debugging facility. It was a bad choice,
sorry for inconvenience.
New in 1.5.1:
API Changes
* Types
- Communication-level errors DEIO and DETIMEOUT are now know as ECOMIO,
ECOMTIMEOUT respectively
- Common device-level errors DEINVAL and DEABORT are now know as EINVALARG,
EOPABORT respectively
- New errors: EFRAACKMISMATCH, EFRAISERRFRAME, EDEVNOTSUP and ENOTIMPL
* Functions
- nfc_abort_command() returns a boolean
- timeout (struct timeval) pointer added to
nfc_initiator_transceive_bytes(), nfc_target_send_bytes() and
nfc_target_receive_bytes()
- timed functions nfc_initiator_transceive_bytes_timed() and
nfc_initiator_transceive_bits_timed() now takes uint32_t as cycles
pointer
- nfc_initiator_poll_targets() renamed to nfc_initiator_poll_target() and
only return one target
New in 1.5.0:
Installed files
- nfc-message.h have been removed, internal macros are not part of API.
- New nfc-emulation.h file offers a middle level API to handle emulation (see
nfc-emulate-forum-tag4 example)
API Changes
* Types
- New error: DEABORT raised when operation is aborted by user (using
nfc_abort_command())
- nfc_chip_t type removed from public API (have been renamed to pn53x_type
in chips/pn53x)
- nfc_device_spec_t removed, each driver can use his own way to keep a
connection pointer
* Structures
- nfc_device_t now have a nfc_driver_t struct pointer (named .driver) and
void pointer (.driver_data) to handle device specific wrapping
- nfc_device_t now have a void pointer (.chip_data) to keep some chip
specific data
- nfc_device_t now have an file descriptor array to manage to abort request
- nfc_device_t does have .nc member (nfc_chip_t) anymore (different chips
handling in now in chip level)
- nfc_device_t does have .nds member (nfc_device_spec_t) anymore, each
driver handle its communication using driver_data pointer
- nfc_device_t does have .bActive member (bool) anymore, this variable was
almost not used and was not efficient
- nfc_device_t does have chip's register caches anymore, this is handle in
chip level (using chip_data pointer)
- driver_callbacks structure have been removed from public API
- New nfc_emulator structure used by the new emulation API (see
nfc_emulate_target())
- New nfc_emulation_state_machine structure used by the new emulation API,
it handles an I/O function and data pointer to create a software based
state-machine.
* Functions
- New nfc_abort_command() function to abort current running command.
- New nfc_initiator_transceive_bits_timed() and
nfc_initiator_transceive_bytes_timed() to transceive bits/bytes and
measure the time to have a reply
- New nfc_emulate_target() function to start a target emulation using an
nfc_emulator structure (it contains a custom state-machine
(nfc_emulation_state_machine struct) and a custom target (nfc_target_t)
(see nfc-emulate-forum-tag4 to have a look on how-to use it)
New in 1.4.1:
API Changes
* Types
- New error: ETGUIDNOTSUP raised when UID is not 4 bytes long or does not
start with 0x08 (Security restriction present in the NXP PN53x chips)
New in 1.4.0:
API Changes
* Types
- New nfc_device_option value (enum): NDO_FORCE_ISO14443_A to force the
chip to switch in ISO14443-A
- New nfc_dep_mode_t (enum) for DEP mode:
NDM_UNDEFINED, NDM_PASSIVE, NDM_ACTIVE
- New nfc_modulation_type_t (enum) that lists modulation types:
NMT_ISO14443A, NMT_ISO14443B, NMT_FELICA, NMT_JEWEL, NMT_DEP
- New nfc_baud_rate_t (enum): list of baud rates:
NBR_UNDEFINED, NBR_106, NBR_212, NBR_424, NBR_847
- nfc_target_type_t have been removed from API (use nfc_modulation_t
instead)
* Structures
- nfc_device_t now have a boolean bAutoIso14443_4 to keep the locally the
state of NDO_AUTO_ISO14443_4 (should not be directly set, use
nfc_configure() with NDO_AUTO_ISO14443_4)
- nfc_device_t now have an uint8_t ui8Parameters to cache PN53x parameters
- nfc_device_t now have a byte_t btSupportByte to cache supported
modulations
- nfc_dep_info_t have completely changed, please see API documentation
- nfc_iso14443b_info_t have completely changed, please see API
documentation
- nfc_modulation_t have completely changed: it now contains a
nfc_modulation_type_t and nfc_baud_rate_t couple. Initialization example:
nfc_modulation_t nm = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
- nfc_target_t now contains new nfc_modulation_t instead of
nfc_target_type_t. Initialization example:
nfc_target_t nt = {
.nm.nmt = NMT_ISO14443A,
.nm.nbr = NBR_UNDEFINED,
.nti.nai.abtAtqa = { 0x03, 0x44 },
.nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef },
.nti.nai.btSak = 0x20,
.nti.nai.szUidLen = 4,
.nti.nai.abtAts = { 0x75, 0x77, 0x81, 0x02, 0x80 },
.nti.nai.szAtsLen = 5,
};
* Functions
- nfc_initiator_select_passive_target() now use new nfc_modulation_t and
nfc_target_t instead of nfc_target_info_t
- nfc_initiator_list_passive_targets() now use new nfc_modulation_t and
nfc_target_t instead of nfc_target_info_t
- nfc_initiator_poll_targets() use new nfc_modulation_t instead of
nfc_target_type_t
- nfc_initiator_select_dep_target() completely changed, use now
nfc_dep_mode_t, nfc_baudrate_t, nfc_dep_info_t and nfc_target_t, please
see API documentation
- nfc_target_init() have an additional argument: nfc_target_t to describe
the wanted target
- append_iso14443a_crc() was renamed to iso14443a_crc_append()
- New iso14443a_locate_historical_bytes() to locate historical bytes in ATS
New in 1.3.9 (since 1.3.4):
Installed files
- mifaretag.h and mifareultag.h are removed, Mifare features are not a part
of libnfc API anymore (these features are always available in examples/)
API Changes
* Types
- New nfc_device_option_t value (enum): NDO_AUTO_14443_4, an option to
enable/disable auto-switching to ISO/IEC 14443-4 if device is compliliant
- New nfc_device_option_t value (enum): NDO_EASY_FRAMING, an option to
enable/disable automatic frames encapsulation and chaining
- New nfc_target_type_t (enum), with values like NTT_MIFARE,
NTT_ISO14443B_106, NTT_DEP_ACTIVE_424, etc.
- Mifare related types have been removed from API: mifare_cmd,
mifare_param_auth, mifare_param_data, mifare_param_value, mifare_param
* Structures
- nfc_device_t now have boolean bEasyFraming to enable/disable "easy
framing" feature (should not be directly set, use nfc_configure() with
NDO_EASY_FRAMING)
- nfc_device_t now have integer iLastError to handle last error
- New chip_callbacks to handle error lookup per chip
- driver_callbacks now have a pointer to chip_callbacks
- New nfc_target_t that contains nfc_target_info_t and nfc_target_type_t
* Functions
- nfc_initiator_select_tag() became nfc_initiator_select_passive_target()
- New nfc_initiator_list_passive_targets() returns a list of detected
target on desired modulation
- (experimental) New nfc_initiator_poll_targets() returns targets that are
detected during hardware polling (available only with PN532)
- nfc_initiator_transceive_dep_bytes(), nfc_target_receive_dep_bytes() and
nfc_target_send_dep_bytes() have been removed from API, use
NDO_EASY_FRAMING option to switch from raw mode to "easy framing"
- nfc_initiator_mifare_cmd() have been removed: no more Mifare related
stuff in libnfc's API
- New nfc_strerror(), nfc_strerror_r() and nfc_perror() to report errors
- New append_iso14443a_crc() to append iso14443a_crc() to a string
New in 1.3.4 (since 1.2.1):
Installed files
- Headers are now installed in include/nfc instead of include/libnfc
- libnfc.h have been renamed to nfc.h
- defines.h and types.h have been merge into nfc-types.h
- bitutils.h is not installed anymore, some functions are now in
examples/nfc-utils.c
- devices.h, dev_acr122.h, dev_arygon.h, dev_pn531.h, dev_pn533.h and rs232.h
are not installed anymore
- New header mifareultag.h, like mifaretag.h for Mifare UltraLight
- New header nfc-messages.h with messages macros (DBG, ERR, INFO)
API Changes
* Types
- uint32_t which was used as size now are size_t
- chip_type became nfc_chip_t (enum)
- init_modulation became nfc_modulation_t (enum), and now have
NM_ACTIVE_DEP and NM_PASSIVE_DEP modulation values added
* Structures
- dev_info became nfc_device_t
- dev_config_option became nfc_device_option_t
- New nfc_device_desc_t to describe the way to access to a NFC device.
Initialisation example:
nfc_device_desc_t ndd = {
ndd.pcDriver = "ARYGON";
ndd.pcPort = "/dev/ttyUSB0";
ndd.uiSpeed = 115200;
};
- dev_callbacks became driver_callbacks and now have two function pointers
more: pick_device() and list_devices()
- New nfc_dep_info_t to handle DEP targets info
- tag_info_iso14443a became nfc_iso14443a_info_t
- tag_info_iso14443b became nfc_iso14443b_info_t
- tag_info_felica became nfc_felica_info_t
- tag_info_jewel became nfc_jewel_info_t
- tag_info became nfc_target_info_t, and now have extended union to
nfc_dep_info_t
* Functions
- nfc_connect() now takes 1 nfc_devive_desc_t argument (can be NULL)
- New nfc_list_devices(), it find available NFC devices using all know
drivers
- (experimental) New nfc_initiator_select_dep(), it looks for DEP targets
- (experimental) New nfc_initiator_transceive_dep_bytes(), like
nfc_initiator_transceive_bytes() for DEP targets
- (experimental) New nfc_target_receive_dep_bytes() and
nfc_target_send_dep_bytes(), to receive/send bytes to DEP target
(configured as initiator) while local NFC device is configured as target
- New nfc_device_name() returns the device's name
- New iso14443a_crc() computes CRC as described in ISO/IEC 14443
- New nfc_version() returns the actual version of libnfc (with SVN
revision, if available)

24
README Normal file
View File

@ -0,0 +1,24 @@
------------------------------------------------------------------------
Public platform independent Near Field Communication (NFC) library
Copyright (C) 2009, Roel Verdult
------------------------------------------------------------------------
Welcome to the developers community of libnfc.
Since it is hard to keep all information up to date
we decided to only maintain the online documentation.
Please visit the official website for more info:
http://www.libnfc.org
If you have questions, remarks, bug-reports, we encourage you to
post this in the developers community:
http://www.libnfc.org/community
------------------------------------------------------------------------
Proprietary Notes:
FeliCa is s registered trademark of the Sony Corporation. MIFARE is a
trademark of NXP Semiconductors. Jewel Topaz is a trademark of Innovision
Research & Technology. All other trademarks are the property of their
respective owners.

View File

@ -1,70 +0,0 @@
*-
* Free/Libre Near Field Communication (NFC) library
*
* Libnfc historical contributors:
* Copyright (C) 2009 Roel Verdult
* Copyright (C) 2009-2013 Romuald Conty
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* Additional contributors of Windows-specific parts:
* Copyright (C) 2010 Glenn Ergeerts
* Copyright (C) 2013 Alex Lian
-*
Requirements
============
- MinGW-w64 compiler toolchain [1]
- LibUsb-Win32 1.2.5.0 (or greater) [2]
- CMake 2.8 [3]
This was tested on Windows 7 64 bit, but should work on Windows Vista and
Windows XP and 32 bit as well.
Only the ACS ACR122 and the ASK Logo readers are tested at the moment, so any feedback about other devices is very welcome.
Community forum: http://www.libnfc.org/community/
Building
========
To build the distribution the MinGW Makefiles generator of CMake was used. Here
is an example of how to generate a distribution with the above mentioned
requirements fulfilled (it is assumed the CMake binaries are in the system
path, this is optional during installation of CMake):
- Add the following directories to your PATH:
c:\MinGW64\bin;c:\MinGW64\x86_64-w64-mingw32\lib32;c:\MinGW64\x86_64-w64-mingw32\include
- Now it is possible to run CMake and mingw32-make:
C:\dev\libnfc-read-only> mkdir ..\libnfc-build
C:\dev\libnfc-read-only> cd ..\libnfc-build
C:\dev\libnfc-build> cmake-gui .
Now you can configure the build. Press "Configure", specify "MinGW32 Makefiles"
and then you have the opportunity to set some configuration variables. If you
don't want a Debug build change the variable CMAKE_BUILD_TYPE to "Release".
If a non-GUI solution is preferred one can use:
C:\dev\libnfc-build> cmake -G "MinGW Makefiles"
-DCMAKE_BUILD_TYPE=Release ..\libnfc-read-only
Now run mingw32-make to build:
C:\dev\libnfc-read-only\bin> mingw32-make
The build will create a shared library for Windows (nfc.dll) to link your applications against. It will compile
the tools against this shared library.
References
==========
[1] the easiest way is to use the TDM-GCC installer.
Make sure to select MinGW-w64 in the installer, the regular MinGW does not contain headers for PCSC.
http://sourceforge.net/projects/tdm-gcc/files/TDM-GCC%20Installer/tdm64-gcc-4.5.1.exe/download
[2] http://sourceforge.net/projects/libusb-win32/files/
[3] http://www.cmake.org

250
README.md
View File

@ -1,250 +0,0 @@
```
*-
* Free/Libre Near Field Communication (NFC) library
*
* Libnfc historical contributors:
* Copyright (C) 2009 Roel Verdult
* Copyright (C) 2009-2015 Romuald Conty
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* Additional contributors:
* See AUTHORS file
-*
```
General Information
===================
libnfc is a library which allows userspace application access to NFC devices.
The official web site is:
http://www.nfc-tools.org/
The official forum site is:
http://www.libnfc.org/community/
The official development site is:
https://github.com/nfc-tools/libnfc
Important note: this file covers POSIX systems, for Windows please read README-Windows.md
Requirements
============
Some NFC drivers depend on third party software:
* pn53x_usb & acr122_usb:
- libusb-0.1 http://libusb.sf.net
* acr122_pcsc:
- pcsc-lite https://pcsclite.apdu.fr/
- pcsc:
- Support build with pcsc driver, which can be using all compatible readers, Feitian R502 and bR500 already passed the test.
The regression test suite depends on the cutter framework:
http://cutter.sf.net
Building
========
Note: If working directly from a git clone of the repository, some of the files need to be generated first. To do this run
`autoreconf -vis`
Alternatively use a .tar.bz2 version of a packaged release (which already contains ./configure):
https://github.com/nfc-tools/libnfc/releases/
The build should be as simple as running these commands:
./configure
make
To build with specific driver(s), see option `--with-drivers=...` detailed in `./configure --help`.
Installation
============
make install
You may need to grant permissions to your user to drive your device.
Under GNU/Linux systems, if you use udev, you could use the provided udev rules.
e.g. under Debian, Ubuntu, etc.
sudo cp contrib/udev/93-pn53x.rules /lib/udev/rules.d/
Under FreeBSD, if you use devd, there is also a rules file: contrib/devd/pn53x.conf.
Configuration
=============
In order to change the default behavior of the library, the libnfc uses a
configuration file located in sysconfdir (as provided to ./configure).
A sample commented file is available in sources: libnfc.conf.sample
If you have compiled using:
./configure --prefix=/usr --sysconfdir=/etc
you can make configuration directory and copy the sample file:
sudo mkdir /etc/nfc
sudo cp libnfc.conf.sample /etc/nfc/libnfc.conf
To configure multiple devices, you can either modify libnfc.conf or create a
file per device in a nfc/devices.d directory:
sudo mkdir -p /etc/nfc/devices.d
printf 'name = "My first device"\nconnstring = "pn532_uart:/dev/ttyACM0"\n' | sudo tee /etc/nfc/devices.d/first.conf
printf 'name = "My second device"\nconnstring = "pn532_uart:/dev/ttyACM1"\n' | sudo tee /etc/nfc/devices.d/second.conf
Environment Variables
=====================
You can override certain configuration options at runtime using the following environment variables:
+ `LIBNFC_DEFAULT_DEVICE=<connstring>`: `LIBNFC_DEFAULT_DEVICE=pn532_uart:/dev/ttyACM0` will use pn532 on /dev/ttyACM0 as default device
+ `LIBNFC_DEVICE=<connstring>` will ignore all devices in the config files and use only the one defined in the variable
+ `LIBNFC_AUTO_SCAN=<true|false>` overrides `allow_autoscan` option in the config file
+ `LIBNFC_INTRUSIVE_SCAN=<true|false>` overrides `allow_intrusive_scan` option in the config file
+ `LIBNFC_LOG_LEVEL=<0|1|2|3>` overrides `log_level` option in the config file
To obtain the connstring of a recognized device, you can use `nfc-scan-device`: `LIBNFC_AUTO_SCAN=true nfc-scan-device` will show the names & connstrings of all found devices.
How to report bugs
==================
To report a bug, visit https://github.com/nfc-tools/libnfc/issues and fill
out a bug report form.
If you have questions, remarks, we encourage you to post this in the developers
community:
http://www.libnfc.org/community
Please make sure to include:
* The version of libnfc
* Information about your system. For instance:
- What operating system and version
- For Linux, what version of the C library
And anything else you think is relevant.
* A trace with debug activated.
Reproduce the bug with debug, e.g. if it was:
$ nfc-list -v
run it as:
$ LIBNFC_LOG_LEVEL=3 nfc-list -v
* How to reproduce the bug.
Please include a short test program that exhibits the behavior.
As a last resort, you can also provide a pointer to a larger piece
of software that can be downloaded.
* If the bug was a crash, the exact text that was printed out
when the crash occured.
* Further information such as stack traces may be useful, but
is not necessary.
Patches
=======
Patches can be posted to https://github.com/nfc-tools/libnfc/issues
If the patch fixes a bug, it is usually a good idea to include
all the information described in "How to Report Bugs".
Troubleshooting
===============
Touchatag/ACR122:
-----------------
If your Touchatag or ACR122 device fails being detected by libnfc, make sure
that PCSC-lite daemon (`pcscd`) is installed and is running.
If your Touchatag or ACR122 device fails being detected by PCSC-lite daemon
(`pcsc_scan` doesn't see anything) then try removing the bogus firmware detection
of libccid: edit libccid_Info.plist configuration file (usually
`/etc/libccid_Info.plist`) and locate `<key>ifdDriverOptions</key>`, turn
`<string>0x0000</string>` value into `0x0004` to allow bogus devices and restart
pcscd daemon.
ACR122:
-------
Using an ACR122 device with libnfc and without tag (e.g. to use NFCIP modes or
card emulation) needs yet another PCSC-lite tweak: You need to allow usage of
CCID Exchange command. To do this, edit `libccid_Info.plist` configuration file
(usually `/etc/libccid_Info.plist`) and locate `<key>ifdDriverOptions</key>`,
turn `<string>0x0000</string>` value into `0x0001` to allow CCID exchange or
`0x0005` to allow CCID exchange and bogus devices (cf previous remark) and
restart pcscd daemon.
Warning: if you use ACS CCID drivers (acsccid), configuration file is located
in something like: `/usr/lib/pcsc/drivers/ifd-acsccid.bundle/Contents/Info.plist`
SCL3711:
--------
Libnfc cannot be used concurrently with the PCSC proprietary driver of SCL3711.
Two possible solutions:
* Either you don't install SCL3711 driver at all
* Or you stop the PCSC daemon when you want to use libnfc-based tools
PN533 USB device on Linux >= 3.1:
---------------------------------
Since Linux kernel version 3.1, a few kernel-modules must not be loaded in order
to use libnfc : "nfc", "pn533" and "pn533_usb".
To prevent kernel from loading automatically these modules, you can blacklist
them in a modprobe conf file. This file is provided within libnfc archive:
sudo cp contrib/linux/blacklist-libnfc.conf /etc/modprobe.d/blacklist-libnfc.conf
FEITIAN bR500 and R502:
-----------------------
Libnfc can work with PCSC proprietary driver of bR500 and R502, which is already available on most Linux setups.
To activate the PCSC support: `./configure --with-drivers=pcsc`.
Readers known to work:
- Feitian bR500
- Feitian R502 Dual interface reader
- Feitian R502 CL(Contactless) reader
These readers are support by CCID since v1.4.25, make sure your CCID driver version higher or equal to 1.4.25.
On MacOS, you can check your CCID version with the following command, and if required, you can install latest CCID driver from [https://github.com/martinpaljak/osx-ccid-installer/releases](https://github.com/martinpaljak/osx-ccid-installer/releases)
```
grep -A 1 CFBundleShortVersionString /usr/local/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
```
On Linux, you can check your CCID version with the following command, and if required, you can install latest CCID driver from [https://ccid.apdu.fr/](https://ccid.apdu.fr/)
```
grep -A 1 CFBundleShortVersionString /usr/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist
```
Proprietary Notes
=================
FeliCa is a registered trademark of the Sony Corporation.
MIFARE is a trademark of NXP Semiconductors.
Jewel Topaz is a trademark of Innovision Research & Technology.
All other trademarks are the property of their respective owners.

View File

@ -1,11 +0,0 @@
INCLUDE(BundleUtilities)
# set bundle to the full path of the executable already existing in the install tree
SET(bundle "${CMAKE_INSTALL_PREFIX}/bin/nfc-list@CMAKE_EXECUTABLE_SUFFIX@")
# set other_libs to a list of additional libs that cannot be reached by dependency analysis
SET(other_libs "")
SET(dirs "@LIBUSB_LIBRARY_DIR@")
fixup_bundle("${bundle}" "${other_libs}" "${dirs}")

View File

@ -1,34 +0,0 @@
# -*- cmake -*-
# Use the following variables to compile and link against LibNFC:
# LIBNFC_FOUND - True if LibNFC was found on your system
# LIBNFC_USE_FILE - The file making LibNFC usable
# LIBNFC_DEFINITIONS - Definitions needed to build with LibNFC
# LIBNFC_INCLUDE_DIR - Directory where nfc/nfc.h can be found
# LIBNFC_INCLUDE_DIRS - List of directories of LibNFC and it's dependencies
# LIBNFC_LIBRARY - LibNFC library location
# LIBNFC_LIBRARIES - List of libraries to link against LibNFC library
# LIBNFC_LIBRARY_DIRS - List of directories containing LibNFC' libraries
# LIBNFC_ROOT_DIR - The base directory of LibNFC
# LIBNFC_VERSION_STRING - A human-readable string containing the version
# LIBNFC_VERSION_MAJOR - The major version of LibNFC
# LIBNFC_VERSION_MINOR - The minor version of LibNFC
# LIBNFC_VERSION_PATCH - The patch version of LibNFC
set ( LIBNFC_FOUND 1 )
set ( LIBNFC_USE_FILE "@LIBNFC_USE_FILE@" )
set ( LIBNFC_DEFINITIONS "@LIBNFC_DEFINITIONS@" )
set ( LIBNFC_INCLUDE_DIR "@LIBNFC_INCLUDE_DIR@" )
set ( LIBNFC_INCLUDE_DIRS "@LIBNFC_INCLUDE_DIRS@" )
set ( LIBNFC_LIBRARY "@LIBNFC_LIBRARY@" )
set ( LIBNFC_LIBRARIES "@LIBNFC_LIBRARIES@" )
set ( LIBNFC_LIBRARY_DIRS "@LIBNFC_LIBRARY_DIRS@" )
set ( LIBNFC_ROOT_DIR "@LIBNFC_ROOT_DIR@" )
set ( LIBNFC_VERSION_STRING "@LIBNFC_VERSION_STRING@" )
set ( LIBNFC_VERSION_MAJOR "@LIBNFC_VERSION_MAJOR@" )
set ( LIBNFC_VERSION_MINOR "@LIBNFC_VERSION_MINOR@" )
set ( LIBNFC_VERSION_PATCH "@LIBNFC_VERSION_PATCH@" )

View File

@ -1,31 +0,0 @@
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version.
# The variable CVF_VERSION must be set before calling configure_file().
set(PACKAGE_VERSION "@LIBNFC_VERSION_STRING@")
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "")
return()
endif()
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
math(EXPR installedBits "8 * 8")
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()

View File

@ -1,9 +0,0 @@
SUBDIRS = modules
EXTRA_DIST = \
FixBundle.cmake.in \
config_posix.h.cmake \
config_windows.h.cmake \
LibNFCConfig.cmake.in \
LibNFCConfigVersion.cmake.in \
UseLibNFC.cmake

View File

@ -1,5 +0,0 @@
# -*- cmake -*-
add_definitions ( ${LIBNFC_DEFINITIONS} )
include_directories ( ${LIBNFC_INCLUDE_DIRS} )
link_directories ( ${LIBNFC_LIBRARY_DIRS} )

View File

@ -1,6 +0,0 @@
#include "contrib/windows.h"
#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@"
#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
#cmakedefine LIBNFC_SYSCONFDIR "@LIBNFC_SYSCONFDIR@"

View File

@ -1,63 +0,0 @@
# This CMake script wants to use libusb functionality, therefore it looks
# for libusb include files and libraries.
#
# Operating Systems Supported:
# - Unix (requires pkg-config)
# Tested with Ubuntu 9.04 and Fedora 11
# - Windows (requires MinGW)
# Tested with Windows XP/Windows 7
#
# This should work for both 32 bit and 64 bit systems.
#
# Author: F. Kooman <fkooman@tuxed.net>
#
# FreeBSD has built-in libusb since 800069
IF(CMAKE_SYSTEM_NAME MATCHES FreeBSD)
EXEC_PROGRAM(sysctl ARGS -n kern.osreldate OUTPUT_VARIABLE FREEBSD_VERSION)
SET(MIN_FREEBSD_VERSION 800068)
IF(FREEBSD_VERSION GREATER ${MIN_FREEBSD_VERSION})
SET(LIBUSB_FOUND TRUE)
SET(LIBUSB_INCLUDE_DIRS "/usr/include")
SET(LIBUSB_LIBRARIES "usb")
SET(LIBUSB_LIBRARY_DIRS "/usr/lib/")
ENDIF(FREEBSD_VERSION GREATER ${MIN_FREEBSD_VERSION})
ENDIF(CMAKE_SYSTEM_NAME MATCHES FreeBSD)
IF(NOT LIBUSB_FOUND)
IF(WIN32)
IF(MINGW)
FIND_PATH(LIBUSB_INCLUDE_DIRS lusb0_usb.h "${CMAKE_CURRENT_BINARY_DIR}/LibUSB-Win32/include" NO_SYSTEM_ENVIRONMENT_PATH)
FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "${CMAKE_CURRENT_BINARY_DIR}/LibUSB-Win32/lib/gcc")
SET(LIBUSB_LIBRARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/LibUSB-Win32/bin/x86/")
ELSE(MINGW)
FIND_PATH(LIBUSB_INCLUDE_DIRS lusb0_usb.h "$ENV{ProgramW6432}/libusb-win32/include" NO_SYSTEM_ENVIRONMENT_PATH)
FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "$ENV{ProgramW6432}/libusb-win32/lib/msvc_x64")
SET(LIBUSB_LIBRARY_DIR "$ENV{ProgramW6432}/libusb-win32/bin/amd64/")
ENDIF(MINGW)
# Must fix up variable to avoid backslashes during packaging
STRING(REGEX REPLACE "\\\\" "/" LIBUSB_LIBRARY_DIR ${LIBUSB_LIBRARY_DIR})
ELSE(WIN32)
# If not under Windows we use PkgConfig
FIND_PACKAGE (PkgConfig)
IF(PKG_CONFIG_FOUND)
PKG_CHECK_MODULES(LIBUSB REQUIRED libusb)
ELSE(PKG_CONFIG_FOUND)
MESSAGE(FATAL_ERROR "Could not find PkgConfig")
ENDIF(PKG_CONFIG_FOUND)
ENDIF(WIN32)
IF(LIBUSB_INCLUDE_DIRS AND LIBUSB_LIBRARIES)
SET(LIBUSB_FOUND TRUE)
ENDIF(LIBUSB_INCLUDE_DIRS AND LIBUSB_LIBRARIES)
ENDIF(NOT LIBUSB_FOUND)
IF(LIBUSB_FOUND)
IF(NOT LIBUSB_FIND_QUIETLY)
MESSAGE(STATUS "Found LIBUSB: ${LIBUSB_LIBRARIES} ${LIBUSB_INCLUDE_DIRS}")
ENDIF (NOT LIBUSB_FIND_QUIETLY)
ELSE(LIBUSB_FOUND)
IF(LIBUSB_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find LIBUSB")
ENDIF(LIBUSB_FIND_REQUIRED)
ENDIF(LIBUSB_FOUND)

View File

@ -1,78 +0,0 @@
SET(LIBNFC_DRIVER_PCSC OFF CACHE BOOL "Enable PC/SC reader support (Depends on PC/SC)")
SET(LIBNFC_DRIVER_ACR122_PCSC OFF CACHE BOOL "Enable ACR122 support (Depends on PC/SC)")
SET(LIBNFC_DRIVER_ACR122_USB ON CACHE BOOL "Enable ACR122 support (Direct USB connection)")
SET(LIBNFC_DRIVER_ACR122S ON CACHE BOOL "Enable ACR122S support (Use serial port)")
SET(LIBNFC_DRIVER_ARYGON ON CACHE BOOL "Enable ARYGON support (Use serial port)")
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
SET(LIBNFC_DRIVER_PN532_I2C ON CACHE BOOL "Enable PN532 I2C support (Use I2C bus)")
SET(LIBNFC_DRIVER_PN532_SPI ON CACHE BOOL "Enable PN532 SPI support (Use SPI bus)")
ELSE(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
SET(LIBNFC_DRIVER_PN532_I2C OFF CACHE BOOL "Enable PN532 I2C support (Use I2C bus)")
SET(LIBNFC_DRIVER_PN532_SPI OFF CACHE BOOL "Enable PN532 SPI support (Use SPI bus)")
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
SET(LIBNFC_DRIVER_PN532_UART ON CACHE BOOL "Enable PN532 UART support (Use serial port)")
SET(LIBNFC_DRIVER_PN53X_USB ON CACHE BOOL "Enable PN531 and PN531 USB support (Depends on libusb)")
IF(LIBNFC_DRIVER_PCSC)
FIND_PACKAGE(PCSC REQUIRED)
ADD_DEFINITIONS("-DDRIVER_PCSC_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/pcsc")
ENDIF(LIBNFC_DRIVER_PCSC)
IF(LIBNFC_DRIVER_ACR122_PCSC)
FIND_PACKAGE(PCSC REQUIRED)
ADD_DEFINITIONS("-DDRIVER_ACR122_PCSC_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/acr122_pcsc")
ENDIF(LIBNFC_DRIVER_ACR122_PCSC)
IF(LIBNFC_DRIVER_ACR122_USB)
FIND_PACKAGE(LIBUSB REQUIRED)
ADD_DEFINITIONS("-DDRIVER_ACR122_USB_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/acr122_usb")
ENDIF(LIBNFC_DRIVER_ACR122_USB)
IF(LIBNFC_DRIVER_ACR122S)
ADD_DEFINITIONS("-DDRIVER_ACR122S_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/acr122s")
SET(UART_REQUIRED TRUE)
ENDIF(LIBNFC_DRIVER_ACR122S)
IF(LIBNFC_DRIVER_ARYGON)
ADD_DEFINITIONS("-DDRIVER_ARYGON_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/arygon")
SET(UART_REQUIRED TRUE)
ENDIF(LIBNFC_DRIVER_ARYGON)
IF(LIBNFC_DRIVER_PN532_I2C)
ADD_DEFINITIONS("-DDRIVER_PN532_I2C_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/pn532_i2c")
SET(I2C_REQUIRED TRUE)
ENDIF(LIBNFC_DRIVER_PN532_I2C)
IF(LIBNFC_DRIVER_PN532_SPI)
ADD_DEFINITIONS("-DDRIVER_PN532_SPI_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/pn532_spi")
SET(SPI_REQUIRED TRUE)
ENDIF(LIBNFC_DRIVER_PN532_SPI)
IF(LIBNFC_DRIVER_PN532_UART)
ADD_DEFINITIONS("-DDRIVER_PN532_UART_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/pn532_uart")
SET(UART_REQUIRED TRUE)
ENDIF(LIBNFC_DRIVER_PN532_UART)
IF(LIBNFC_DRIVER_PN53X_USB)
FIND_PACKAGE(LIBUSB REQUIRED)
ADD_DEFINITIONS("-DDRIVER_PN53X_USB_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/pn53x_usb")
SET(USB_REQUIRED TRUE)
ENDIF(LIBNFC_DRIVER_PN53X_USB)
IF(LIBNFC_DRIVER_ACR122_USB)
FIND_PACKAGE(LIBUSB REQUIRED)
ADD_DEFINITIONS("-DDRIVER_ACR122_USB_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/acr122_usb")
SET(USB_REQUIRED TRUE)
ENDIF(LIBNFC_DRIVER_ACR122_USB)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/libnfc/drivers)

View File

@ -1,6 +0,0 @@
EXTRA_DIST = \
COPYING-CMAKE-SCRIPTS \
FindLIBUSB.cmake \
FindPCSC.cmake \
UseDoxygen.cmake \
LibnfcDrivers.cmake

View File

@ -0,0 +1,66 @@
# This CMake script wants to use libusb functionality, therefore it looks
# for libusb include files and libraries.
#
# Operating Systems Supported:
# - Unix (requires pkg-config)
# Tested with Ubuntu 9.04 and Fedora 11
# - Windows (requires MSVC)
# Tested with Windows XP
#
# This should work for both 32 bit and 64 bit systems.
#
# Author: F. Kooman <fkooman@tuxed.net>
#
# FreeBSD has built-in libusb since 800069
IF(CMAKE_SYSTEM_NAME MATCHES FreeBSD)
EXEC_PROGRAM(sysctl ARGS -n kern.osreldate OUTPUT_VARIABLE FREEBSD_VERSION)
SET(MIN_FREEBSD_VERSION 800068)
IF(FREEBSD_VERSION GREATER ${MIN_FREEBSD_VERSION})
SET(LIBUSB_FOUND TRUE)
SET(LIBUSB_INCLUDE_DIRS "/usr/include")
SET(LIBUSB_LIBRARIES "usb")
SET(LIBUSB_LIBRARY_DIRS "/usr/lib/")
ENDIF(FREEBSD_VERSION GREATER ${MIN_FREEBSD_VERSION})
ENDIF(CMAKE_SYSTEM_NAME MATCHES FreeBSD)
IF(NOT LIBUSB_FOUND)
IF(WIN32)
# Windows with Microsoft Visual C++
FIND_PATH(LIBUSB_INCLUDE_DIRS usb.h "$ENV{ProgramFiles}/LibUSB-Win32/include")
IF(MSVC)
IF(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x64")
# on x64 (win64)
FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "$ENV{ProgramFiles}/LibUSB-Win32/lib/msvc_x64")
ELSE(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x64")
# on x86 (win32)
FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "$ENV{ProgramFiles}/LibUSB-Win32/lib/msvc")
ENDIF(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x64")
ENDIF(MSVC)
IF(MINGW)
FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "$ENV{ProgramFiles}/LibUSB-Win32/lib/gcc")
ENDIF(MINGW)
ELSE(WIN32)
# If not under Windows we use PkgConfig
FIND_PACKAGE (PkgConfig)
IF(PKG_CONFIG_FOUND)
PKG_CHECK_MODULES(LIBUSB REQUIRED libusb)
ELSE(PKG_CONFIG_FOUND)
MESSAGE(FATAL_ERROR "Could not find PkgConfig")
ENDIF(PKG_CONFIG_FOUND)
ENDIF(WIN32)
IF(LIBUSB_INCLUDE_DIRS AND LIBUSB_LIBRARIES)
SET(LIBUSB_FOUND TRUE)
ENDIF(LIBUSB_INCLUDE_DIRS AND LIBUSB_LIBRARIES)
ENDIF(NOT LIBUSB_FOUND)
IF(LIBUSB_FOUND)
IF(NOT LIBUSB_FIND_QUIETLY)
MESSAGE(STATUS "Found LIBUSB: ${LIBUSB_LIBRARIES}")
ENDIF (NOT LIBUSB_FIND_QUIETLY)
ELSE(LIBUSB_FOUND)
IF(LIBUSB_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find LIBUSB")
ENDIF(LIBUSB_FIND_REQUIRED)
ENDIF(LIBUSB_FOUND)

View File

@ -20,7 +20,13 @@ IF(NOT PCSC_FOUND)
# Will find PC/SC headers both on Mac and Windows # Will find PC/SC headers both on Mac and Windows
FIND_PATH(PCSC_INCLUDE_DIRS WinSCard.h) FIND_PATH(PCSC_INCLUDE_DIRS WinSCard.h)
# PCSC library is for Mac, WinSCard library is for Windows # PCSC library is for Mac, WinSCard library is for Windows
FIND_LIBRARY(PCSC_LIBRARIES NAMES PCSC libwinscard) FIND_LIBRARY(PCSC_LIBRARIES NAMES PCSC WinSCard)
IF(MINGW)
# MinGW32 with PCSC framework use Microsoft SDK's WinSCard.h
SET(PCSC_INCLUDE_DIRS)
SET(PCSC_INCLUDE_DIRS "$ENV{ProgramFiles}/Microsoft SDKs/Windows/v7.0/Include")
ENDIF(MINGW)
ENDIF(NOT PCSC_FOUND) ENDIF(NOT PCSC_FOUND)
INCLUDE(FindPackageHandleStandardArgs) INCLUDE(FindPackageHandleStandardArgs)

View File

@ -0,0 +1,36 @@
SET(LIBNFC_DRIVER_ACR122 ON CACHE BOOL "Enable ACR122 support (Depends on PC/SC)")
SET(LIBNFC_DRIVER_PN531_USB ON CACHE BOOL "Enable PN531_USB support (Depends on libusb)")
SET(LIBNFC_DRIVER_PN533_USB ON CACHE BOOL "Enable PN533_USB support (Depends on libusb)")
SET(LIBNFC_DRIVER_ARYGON ON CACHE BOOL "Enable ARYGON support (Use serial port)")
SET(LIBNFC_DRIVER_PN532_UART OFF CACHE BOOL "Enable PN533_USB support (Use serial port)")
IF(LIBNFC_DRIVER_ACR122)
FIND_PACKAGE(PCSC REQUIRED)
ADD_DEFINITIONS("-DDRIVER_ACR122_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/acr122")
ENDIF(LIBNFC_DRIVER_ACR122)
IF(LIBNFC_DRIVER_PN531_USB)
FIND_PACKAGE(LIBUSB REQUIRED)
ADD_DEFINITIONS("-DDRIVER_PN531_USB_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/pn531_usb" "drivers/pn53x_usb.c")
ENDIF(LIBNFC_DRIVER_PN531_USB)
IF(LIBNFC_DRIVER_PN533_USB)
FIND_PACKAGE(LIBUSB REQUIRED)
ADD_DEFINITIONS("-DDRIVER_PN533_USB_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/pn533_usb" "drivers/pn53x_usb.c")
ENDIF(LIBNFC_DRIVER_PN533_USB)
IF(LIBNFC_DRIVER_ARYGON)
ADD_DEFINITIONS("-DDRIVER_ARYGON_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} drivers/arygon)
ENDIF(LIBNFC_DRIVER_ARYGON)
IF(LIBNFC_DRIVER_PN532_UART)
ADD_DEFINITIONS("-DDRIVER_PN532_UART_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} drivers/pn532_uart)
ENDIF(LIBNFC_DRIVER_PN532_UART)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/drivers)

View File

@ -0,0 +1 @@
EXTRA_DIST = COPYING-CMAKE-SCRIPTS FindLIBUSB.cmake FindPCSC.cmake UseDoxygen.cmake

View File

@ -91,7 +91,8 @@ if(DOXYGEN_FOUND AND DOXYFILE_IN)
configure_file(${DOXYFILE_IN} Doxyfile ESCAPE_QUOTES IMMEDIATE @ONLY) configure_file(${DOXYFILE_IN} Doxyfile ESCAPE_QUOTES IMMEDIATE @ONLY)
if(NOT TARGET doc) get_target_property(DOC_TARGET doc TYPE)
if(NOT DOC_TARGET)
add_custom_target(doc) add_custom_target(doc)
endif() endif()

View File

@ -2,4 +2,3 @@
#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@" #cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@" #cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
#cmakedefine _XOPEN_SOURCE @_XOPEN_SOURCE@ #cmakedefine _XOPEN_SOURCE @_XOPEN_SOURCE@
#cmakedefine SYSCONFDIR "@SYSCONFDIR@"

View File

@ -1,30 +1,28 @@
# General init # General init
# /!\ Don't forget to update 'CMakeLists.txt' too /!\ # /!\ Don't forget to update 'windows/Makefile' too /!\
AC_INIT([libnfc],[1.8.0],[nfc-tools@googlegroups.com]) AC_INIT(libnfc, 1.4.0, info@libnfc.org)
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADER(config.h) AC_CONFIG_HEADER(config.h)
# GIT revison # SVN revison
GIT_REVISION=`which git > /dev/null && git describe` define([svn_revision], esyscmd([sh -c "svnversion -n"]))
if test x"$GIT_REVISION" != x""; then SVN_REVISION=svn_revision
AC_DEFINE_UNQUOTED([GIT_REVISION], ["$GIT_REVISION"], [GIT revision]) AC_DEFINE_UNQUOTED([SVN_REVISION], ["$SVN_REVISION"], [SVN revision])
fi
AM_INIT_AUTOMAKE(subdir-objects dist-bzip2 no-dist-gzip foreign) AM_INIT_AUTOMAKE
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
AC_LANG([C]) AC_LANG_C
AC_PROG_CC AC_PROG_CC
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
WITH_POSIX_ONLY_EXAMPLES=1 WITH_POSIX_ONLY_EXAMPLES=1
# Libtool # Libtool
LT_INIT AC_PROG_LIBTOOL
case "$host" in case "$host" in
*-pc-linux-gnu) *-pc-linux-gnu)
AC_MSG_RESULT([Fixing libtool for -rpath problems.]) AC_MSG_RESULT([Fixing libtool for -rpath problems.])
@ -39,22 +37,23 @@ case "$host" in
esac esac
AM_CONDITIONAL(POSIX_ONLY_EXAMPLES_ENABLED, [test "$WITH_POSIX_ONLY_EXAMPLES" = "1"]) AM_CONDITIONAL(POSIX_ONLY_EXAMPLES_ENABLED, [test "$WITH_POSIX_ONLY_EXAMPLES" = "1"])
PKG_PROG_PKG_CONFIG AC_PATH_PROG(PKG_CONFIG, pkg-config)
if test x"$PKG_CONFIG" = x""; then
AC_MSG_ERROR([pkg-config not found.])
fi
# Checks for header files. # Checks for header files.
AC_HEADER_STDC AC_HEADER_STDC
AC_HEADER_STDBOOL AC_HEADER_STDBOOL
AC_CHECK_HEADERS([fcntl.h limits.h stdio.h stdlib.h stdint.h stddef.h stdbool.h sys/ioctl.h sys/param.h sys/time.h termios.h]) AC_CHECK_HEADERS([fcntl.h limits.h stdio.h stdlib.h stdint.h stddef.h stdbool.h sys/ioctl.h sys/param.h sys/time.h termios.h])
AC_CHECK_HEADERS([linux/spi/spidev.h], [spi_available="yes"])
AC_CHECK_HEADERS([linux/i2c-dev.h], [i2c_available="yes"])
AC_CHECK_HEADERS([linux_nfc_api.h], [nfc_nci_available="yes"])
AC_CHECK_FUNCS([memmove memset select strdup strerror strstr strtol usleep], AC_CHECK_FUNCS([memmove memset select strdup strerror strstr strtol usleep],
[AC_DEFINE([_XOPEN_SOURCE], [600], [Enable POSIX extensions if present])]) [AC_DEFINE([_XOPEN_SOURCE], [600], [Enable POSIX extensions if present])])
AC_DEFINE(_NETBSD_SOURCE, 1, [Define on NetBSD to activate all library features]) AC_DEFINE(_NETBSD_SOURCE, 1, [Define on NetBSD to activate all library features])
AC_DEFINE(_DARWIN_C_SOURCE, 1, [Define on Darwin to activate all library features]) AC_DEFINE(_DARWIN_C_SOURCE, 1, [Define on Darwin to activate all library features])
# Note: malloc function should be tested but it produces some error while cross-compiling with MinGW # XXX malloc function should be tested
# but it produces some error while cross-compiling with MinGW
# AC_FUNC_MALLOC # AC_FUNC_MALLOC
# Checks for types # Checks for types
@ -63,82 +62,36 @@ AC_TYPE_UINT8_T
AC_TYPE_UINT16_T AC_TYPE_UINT16_T
AC_TYPE_UINT32_T AC_TYPE_UINT32_T
AC_TYPE_UINT64_T AC_TYPE_UINT64_T
AC_TYPE_INT16_T
AC_TYPE_INT32_T AC_TYPE_INT32_T
AC_TYPE_OFF_T
AC_TYPE_SIGNAL
LIBNFC_CFLAGS='-I$(top_srcdir)/libnfc -I$(top_builddir)/include -I$(top_srcdir)/include' LIBNFC_CFLAGS='-I$(top_srcdir)/libnfc -I$(top_builddir)/include -I$(top_srcdir)/include'
AC_SUBST(LIBNFC_CFLAGS) AC_SUBST(LIBNFC_CFLAGS)
# Log support (default:yes)
AC_ARG_ENABLE([log],AS_HELP_STRING([--disable-log],[Disable any logs]),[enable_log=$enableval],[enable_log="yes"])
AC_MSG_CHECKING(for log flag)
AC_MSG_RESULT($enable_log)
AM_CONDITIONAL([WITH_LOG], [test "$enable_log" != "no"])
if test x"$enable_log" = "xyes"
then
AC_DEFINE([LOG], [1], [Enable log])
fi
# Conffiles support (default:yes)
AC_ARG_ENABLE([conffiles],AS_HELP_STRING([--disable-conffiles],[Disable use of config files]),[enable_conffiles=$enableval],[enable_conffiles="yes"])
AC_MSG_CHECKING(for conffiles flag)
AC_MSG_RESULT($enable_conffiles)
AM_CONDITIONAL([WITH_CONFFILES], [test "$enable_conffiles" != "no"])
if test x"$enable_conffiles" = "xyes"
then
AC_DEFINE([CONFFILES], [1], [Enable conffiles])
fi
# Envvars support (default:yes)
AC_ARG_ENABLE([envvars],AS_HELP_STRING([--disable-envvars],[Disable use of environment variables]),[enable_envvars=$enableval],[enable_envvars="yes"])
AC_MSG_CHECKING(for envvars flag)
AC_MSG_RESULT($enable_envvars)
AM_CONDITIONAL([WITH_ENVVARS], [test "$enable_envvars" != "no"])
if test x"$enable_envvars" = "xyes"
then
AC_DEFINE([ENVVARS], [1], [Enable envvars])
fi
# Debug support (default:no) # Debug support (default:no)
AC_ARG_ENABLE([debug],AS_HELP_STRING([--enable-debug],[Enable debug mode]),[enable_debug=$enableval],[enable_debug="no"]) AC_ARG_ENABLE([debug],AS_HELP_STRING([--enable-debug],[Enable debug output]),[enable_debug=$enableval],[enable_debug="no"])
AC_MSG_CHECKING(for debug flag) AC_MSG_CHECKING(for debug flag)
AC_MSG_RESULT($enable_debug) AC_MSG_RESULT($enable_debug)
AM_CONDITIONAL([WITH_DEBUG], [test "$enable_debug" != "no"])
if test x"$enable_debug" = "xyes" if test x"$enable_debug" = "xyes"
then then
AC_DEFINE([DEBUG], [1], [Enable debug flag]) CFLAGS="$CFLAGS -g -Wall -DDEBUG -pedantic -O0 -ggdb"
CFLAGS="$CFLAGS -g -O0 -ggdb"
fi fi
# Handle --with-drivers option # Handle --with-drivers option
LIBNFC_ARG_WITH_DRIVERS LIBNFC_ARG_WITH_DRIVERS
# Enable UART if # Serial autoprobing support (default:no)
AM_CONDITIONAL(UART_ENABLED, [test x"$uart_required" = x"yes"]) AC_ARG_ENABLE([serial-autoprobe],AS_HELP_STRING([--enable-serial-autoprobe],[Allow serial ports to be probed (can seriously disturb connected serial devices)]),[enable_serial_autoprobe=$enableval],[enable_serial_autoprobe="no"])
AC_MSG_CHECKING(for serial autoprobe flag)
AC_MSG_RESULT($enable_serial_autoprobe)
# Enable SPI if if test x"$enable_serial_autoprobe" = "xyes"
AM_CONDITIONAL(SPI_ENABLED, [test x"$spi_required" = x"yes"])
# Enable I2C if
AM_CONDITIONAL(I2C_ENABLED, [test x"$i2c_required" = x"yes"])
if test x"$i2c_required" = x"yes"
then then
AC_SEARCH_LIBS([clock_gettime], [rt]) CFLAGS="$CFLAGS -DSERIAL_AUTOPROBE_ENABLED"
fi
# Enable Libnfc-NCI if required
if test x"$nfc_nci_required" = x"yes"
then
PKG_CHECK_MODULES([LIBNFC_NCI], [libnfc-nci],
[AC_MSG_NOTICE([libnfc-nci present])],
[AC_MSG_ERROR([libnfc-nci not present but required for some drivers configuration])]
)
CFLAGS="$CFLAGS $LIBNFC_NCI_CFLAGS"
fi fi
# Documentation (default: no) # Documentation (default: no)
@ -157,13 +110,15 @@ then
fi fi
AM_CONDITIONAL(DOC_ENABLED, [test x"$enable_doc" = xyes]) AM_CONDITIONAL(DOC_ENABLED, [test x"$enable_doc" = xyes])
# Example build (default: yes) # The indent target require GNU indent
AC_ARG_ENABLE([example],AS_HELP_STRING([--enable-example],[Enable example build.]),[enable_example=$enableval],[enable_example="yes"]) AC_PATH_PROG([INDENT], [indent])
AC_PATH_PROG([GINDENT], [gindent])
if test x"$GINDENT" != x""; then
INDENT="$GINDENT"
fi
AC_MSG_CHECKING(for example build) AC_SUBST(INDENT)
AC_MSG_RESULT($enable_example) AM_CONDITIONAL(HAS_INDENT, [test x"$INDENT" != x""])
AM_CONDITIONAL(EXAMPLE_ENABLED, [test x"$enable_example" = xyes])
# Dependencies # Dependencies
PKG_CONFIG_REQUIRES="" PKG_CONFIG_REQUIRES=""
@ -176,20 +131,14 @@ AC_SUBST(PKG_CONFIG_REQUIRES)
AM_CONDITIONAL(LIBUSB_ENABLED, [test "$HAVE_LIBUSB" = "1"]) AM_CONDITIONAL(LIBUSB_ENABLED, [test "$HAVE_LIBUSB" = "1"])
AM_CONDITIONAL(PCSC_ENABLED, [test "$HAVE_PCSC" = "1"]) AM_CONDITIONAL(PCSC_ENABLED, [test "$HAVE_PCSC" = "1"])
CUTTER_REQUIRED_VERSION=1.1.7 CUTTER_REQUIRED_VERSION=1.1.2
m4_ifdef([AC_CHECK_CUTTER], [AC_CHECK_CUTTER([>= $CUTTER_REQUIRED_VERSION])], [ac_cv_use_cutter="no"]) m4_ifdef([AC_CHECK_CUTTER], [AC_CHECK_CUTTER([>= $CUTTER_REQUIRED_VERSION])], [ac_cv_use_cutter="no"])
if test x$ac_cv_with_cutter = xyes -a x$ac_cv_use_cutter = xno; then if test x$ac_cv_with_cutter = xyes -a x$ac_cv_use_cutter = xno; then
AC_MSG_ERROR([cutter >= $CUTTER_REQUIRED_VERSION is mandatory.]) AC_MSG_ERROR([cutter >= $CUTTER_REQUIRED_VERSION is mandatory.])
fi fi
AM_CONDITIONAL([WITH_CUTTER], [test "$ac_cv_use_cutter" != "no"]) AM_CONDITIONAL([WITH_CUTTER], [test "$ac_cv_use_cutter" != "no"])
if test x"$enable_example" = "xyes"
then
AC_CHECK_READLINE AC_CHECK_READLINE
fi
# Help us to write great code ;-)
CFLAGS="$CFLAGS -Wall -pedantic -Wextra"
# Defines and C flags # Defines and C flags
CFLAGS="$CFLAGS -std=c99" CFLAGS="$CFLAGS -std=c99"
@ -198,30 +147,18 @@ CFLAGS="$CFLAGS -std=c99"
CFLAGS="$CFLAGS -Du_int8_t=uint8_t -Du_int16_t=uint16_t" CFLAGS="$CFLAGS -Du_int8_t=uint8_t -Du_int16_t=uint16_t"
AC_CONFIG_FILES([ AC_CONFIG_FILES([
Doxyfile
Makefile Makefile
cmake/Makefile
cmake/modules/Makefile
contrib/Makefile
contrib/devd/Makefile
contrib/libnfc/Makefile
contrib/linux/Makefile
contrib/udev/Makefile
contrib/win32/Makefile
contrib/win32/sys/Makefile
contrib/win32/libnfc/Makefile
contrib/win32/libnfc/buses/Makefile
examples/Makefile
examples/pn53x-tamashell-scripts/Makefile
include/Makefile include/Makefile
include/nfc/Makefile include/nfc/Makefile
libnfc.pc
libnfc/Makefile
libnfc/buses/Makefile
libnfc/chips/Makefile libnfc/chips/Makefile
libnfc/buses/Makefile
libnfc/drivers/Makefile libnfc/drivers/Makefile
libnfc/Makefile
examples/Makefile
cmake_modules/Makefile
test/Makefile test/Makefile
utils/Makefile libnfc.pc
Doxyfile
]) ])
AC_OUTPUT AC_OUTPUT

View File

@ -1,9 +0,0 @@
SUBDIRS = \
devd \
libnfc \
linux \
udev \
win32
EXTRA_DIST = \
windows.h

View File

@ -1,2 +0,0 @@
EXTRA_DIST = \
pn53x.conf

View File

@ -1,7 +0,0 @@
EXTRA_DIST = \
arygon.conf.sample \
pn532_i2c_on_rpi.conf.sample \
pn532_spi_on_rpi.conf.sample \
pn532_uart_on_rpi_3.conf.sample \
pn532_uart_on_rpi.conf.sample \
pn532_via_uart2usb.conf.sample

View File

@ -1,3 +0,0 @@
## Typical configuration file for Arygon/IDentive device (with Arygon-MCU on board)
name = "IDentive"
connstring = arygon:/dev/ttyS0

View File

@ -1,12 +0,0 @@
## Typical configuration file for PN532 device on R-Pi connected using I2C
## Note: to use SPI port on R-Pi, you have to load kernel modules i2c-bcm2708 and i2c-dev:
## Edit /etc/modprobe.d/raspi-blacklist.conf and comment: #blacklist i2c-bcm2708
## Edit /etc/modules and add a new line: i2c-dev
name = "PN532 board via I2C"
connstring = pn532_i2c:/dev/i2c-0
# Note: If you have an R-Pi revision 2.0, the I2C bus #1 is now routed to connector P1
# (instead of the I2C bus #0 routed on same connector on initial board revision), so
# the configuration to use would probably be:
# connstring = pn532_i2c:/dev/i2c-1

View File

@ -1,5 +0,0 @@
## Typical configuration file for PN532 device on R-Pi connected using SPI
## Note: to use SPI port on R-Pi, you have to load kernel module spi-bcm2708:
## Edit /etc/modprobe.d/raspi-blacklist.conf and comment: #blacklist spi-bcm2708
name = "PN532 board via SPI"
connstring = pn532_spi:/dev/spidev0.0:500000

View File

@ -1,5 +0,0 @@
## Typical configuration file for PN532 device on R-Pi connected using UART
## Note: to use UART port on R-Pi, you have to disable linux serial console:
## http://learn.adafruit.com/adafruit-nfc-rfid-on-raspberry-pi/freeing-uart-on-the-pi
name = "PN532 board via UART"
connstring = pn532_uart:/dev/ttyAMA0

View File

@ -1,22 +0,0 @@
## Typical configuration file for PN532 device on R-Pi 3 connected using miniUART
## Note: Changes have been made to R-Pi 3 with the addition of Bluetooth LE
## The UART is now being used by the BLE module. Instead of disabling it, you can
## use the PN532 device with the "mini UART", which is still hijacked by the linux kernel
## as a serial console
##
## Tested recipe with PN532 breakout from Adafruit
##
## To enable uart on GPIO, add this line to bottom of /boot/config.txt
## enable_uart=1
##
## Stop and disable serial console:
## $ sudo systemctl stop serial-getty@ttyS0.service
## $ sudo systemctl disable serial-getty@ttyS0.service
##
## Remove console from /boot/cmdline.txt by removing:
## console=serial0,115200 Save and reboot for changes to take effect.
##
name = "PN532 board via UART"
connstring = pn532_uart:/dev/ttyS0
allow_intrusive_scan = true

View File

@ -1,3 +0,0 @@
## Typical configuration file for PN532 board (ie. microbuilder.eu / Adafruit) device
name = "Adafruit PN532 board via UART"
connstring = pn532_uart:/dev/ttyUSB0

View File

@ -1,2 +0,0 @@
EXTRA_DIST = \
blacklist-libnfc.conf

View File

@ -1,3 +0,0 @@
blacklist nfc
blacklist pn533
blacklist pn533_usb

View File

@ -1,2 +0,0 @@
EXTRA_DIST = \
93-pn53x.rules

View File

@ -1,8 +0,0 @@
SUBDIRS = libnfc sys .
EXTRA_DIST = \
err.h \
nfc.def \
stdlib.c \
unistd.h \
version.rc.in

View File

@ -1,870 +0,0 @@
/*
* Dirent interface for Microsoft Visual Studio
*
* Copyright (C) 2006-2012 Toni Ronkko
* This file is part of dirent. Dirent may be freely distributed
* under the MIT license. For all details and documentation, see
* https://github.com/tronkko/dirent
*/
#ifndef DIRENT_H
#define DIRENT_H
/*
* Include windows.h without Windows Sockets 1.1 to prevent conflicts with
* Windows Sockets 2.0.
*/
#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
/* Indicates that d_type field is available in dirent structure */
#define _DIRENT_HAVE_D_TYPE
/* Indicates that d_namlen field is available in dirent structure */
#define _DIRENT_HAVE_D_NAMLEN
/* Entries missing from MSVC 6.0 */
#if !defined(FILE_ATTRIBUTE_DEVICE)
# define FILE_ATTRIBUTE_DEVICE 0x40
#endif
/* File type and permission flags for stat(), general mask */
#if !defined(S_IFMT)
# define S_IFMT _S_IFMT
#endif
/* Directory bit */
#if !defined(S_IFDIR)
# define S_IFDIR _S_IFDIR
#endif
/* Character device bit */
#if !defined(S_IFCHR)
# define S_IFCHR _S_IFCHR
#endif
/* Pipe bit */
#if !defined(S_IFFIFO)
# define S_IFFIFO _S_IFFIFO
#endif
/* Regular file bit */
#if !defined(S_IFREG)
# define S_IFREG _S_IFREG
#endif
/* Read permission */
#if !defined(S_IREAD)
# define S_IREAD _S_IREAD
#endif
/* Write permission */
#if !defined(S_IWRITE)
# define S_IWRITE _S_IWRITE
#endif
/* Execute permission */
#if !defined(S_IEXEC)
# define S_IEXEC _S_IEXEC
#endif
/* Pipe */
#if !defined(S_IFIFO)
# define S_IFIFO _S_IFIFO
#endif
/* Block device */
#if !defined(S_IFBLK)
# define S_IFBLK 0
#endif
/* Link */
#if !defined(S_IFLNK)
# define S_IFLNK 0
#endif
/* Socket */
#if !defined(S_IFSOCK)
# define S_IFSOCK 0
#endif
/* Read user permission */
#if !defined(S_IRUSR)
# define S_IRUSR S_IREAD
#endif
/* Write user permission */
#if !defined(S_IWUSR)
# define S_IWUSR S_IWRITE
#endif
/* Execute user permission */
#if !defined(S_IXUSR)
# define S_IXUSR 0
#endif
/* Read group permission */
#if !defined(S_IRGRP)
# define S_IRGRP 0
#endif
/* Write group permission */
#if !defined(S_IWGRP)
# define S_IWGRP 0
#endif
/* Execute group permission */
#if !defined(S_IXGRP)
# define S_IXGRP 0
#endif
/* Read others permission */
#if !defined(S_IROTH)
# define S_IROTH 0
#endif
/* Write others permission */
#if !defined(S_IWOTH)
# define S_IWOTH 0
#endif
/* Execute others permission */
#if !defined(S_IXOTH)
# define S_IXOTH 0
#endif
/* Maximum length of file name */
#if !defined(PATH_MAX)
# define PATH_MAX MAX_PATH
#endif
#if !defined(FILENAME_MAX)
# define FILENAME_MAX MAX_PATH
#endif
#if !defined(NAME_MAX)
# define NAME_MAX FILENAME_MAX
#endif
/* File type flags for d_type */
#define DT_UNKNOWN 0
#define DT_REG S_IFREG
#define DT_DIR S_IFDIR
#define DT_FIFO S_IFIFO
#define DT_SOCK S_IFSOCK
#define DT_CHR S_IFCHR
#define DT_BLK S_IFBLK
#define DT_LNK S_IFLNK
/* Macros for converting between st_mode and d_type */
#define IFTODT(mode) ((mode) & S_IFMT)
#define DTTOIF(type) (type)
/*
* File type macros. Note that block devices, sockets and links cannot be
* distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
* only defined for compatibility. These macros should always return false
* on Windows.
*/
#if !defined(S_ISFIFO)
# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#endif
#if !defined(S_ISDIR)
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
#if !defined(S_ISREG)
# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#endif
#if !defined(S_ISLNK)
# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#endif
#if !defined(S_ISSOCK)
# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#endif
#if !defined(S_ISCHR)
# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#endif
#if !defined(S_ISBLK)
# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
#endif
/* Return the exact length of the file name without zero terminator */
#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
/* Return the maximum size of a file name */
#define _D_ALLOC_NAMLEN(p) ((PATH_MAX)+1)
#ifdef __cplusplus
extern "C" {
#endif
/* Wide-character version */
struct _wdirent {
/* Always zero */
long d_ino;
/* File position within stream */
long d_off;
/* Structure size */
unsigned short d_reclen;
/* Length of name without \0 */
size_t d_namlen;
/* File type */
int d_type;
/* File name */
wchar_t d_name[PATH_MAX+1];
};
typedef struct _wdirent _wdirent;
struct _WDIR {
/* Current directory entry */
struct _wdirent ent;
/* Private file data */
WIN32_FIND_DATAW data;
/* True if data is valid */
int cached;
/* Win32 search handle */
HANDLE handle;
/* Initial directory name */
wchar_t *patt;
};
typedef struct _WDIR _WDIR;
/* Multi-byte character version */
struct dirent {
/* Always zero */
long d_ino;
/* File position within stream */
long d_off;
/* Structure size */
unsigned short d_reclen;
/* Length of name without \0 */
size_t d_namlen;
/* File type */
int d_type;
/* File name */
char d_name[PATH_MAX+1];
};
typedef struct dirent dirent;
struct DIR {
struct dirent ent;
struct _WDIR *wdirp;
};
typedef struct DIR DIR;
/* Dirent functions */
static DIR *opendir (const char *dirname);
static _WDIR *_wopendir (const wchar_t *dirname);
static struct dirent *readdir (DIR *dirp);
static int readdir_r(
DIR *dirp, struct dirent *entry, struct dirent **result);
static int closedir (DIR *dirp);
static int _wclosedir (_WDIR *dirp);
/* For compatibility with Symbian */
#define wdirent _wdirent
#define WDIR _WDIR
#define wopendir _wopendir
#define wreaddir _wreaddir
#define wclosedir _wclosedir
#define wrewinddir _wrewinddir
/* Internal utility functions */
static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
static int dirent_mbstowcs_s(
size_t *pReturnValue,
wchar_t *wcstr,
size_t sizeInWords,
const char *mbstr,
size_t count);
static int dirent_wcstombs_s(
size_t *pReturnValue,
char *mbstr,
size_t sizeInBytes,
const wchar_t *wcstr,
size_t count);
static void dirent_set_errno (int error);
/*
* Open directory stream DIRNAME for read and return a pointer to the
* internal working area that is used to retrieve individual directory
* entries.
*/
static _WDIR*
_wopendir(
const wchar_t *dirname)
{
_WDIR *dirp = NULL;
int error;
/* Must have directory name */
if (dirname == NULL || dirname[0] == '\0') {
dirent_set_errno (ENOENT);
return NULL;
}
/* Allocate new _WDIR structure */
dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
if (dirp != NULL) {
DWORD n;
/* Reset _WDIR structure */
dirp->handle = INVALID_HANDLE_VALUE;
dirp->patt = NULL;
dirp->cached = 0;
/* Compute the length of full path plus zero terminator
*
* Note that on WinRT there's no way to convert relative paths
* into absolute paths, so just assume it is an absolute path.
*/
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
n = wcslen(dirname);
# else
n = GetFullPathNameW (dirname, 0, NULL, NULL);
# endif
/* Allocate room for absolute directory name and search pattern */
dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
if (dirp->patt) {
/*
* Convert relative directory name to an absolute one. This
* allows rewinddir() to function correctly even when current
* working directory is changed between opendir() and rewinddir().
*
* Note that on WinRT there's no way to convert relative paths
* into absolute paths, so just assume it is an absolute path.
*/
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
wcsncpy_s(dirp->patt, n+1, dirname, n);
# else
n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
# endif
if (n > 0) {
wchar_t *p;
/* Append search pattern \* to the directory name */
p = dirp->patt + n;
if (dirp->patt < p) {
switch (p[-1]) {
case '\\':
case '/':
case ':':
/* Directory ends in path separator, e.g. c:\temp\ */
/*NOP*/;
break;
default:
/* Directory name doesn't end in path separator */
*p++ = '\\';
}
}
*p++ = '*';
*p = '\0';
/* Open directory stream and retrieve the first entry */
if (dirent_first (dirp)) {
/* Directory stream opened successfully */
error = 0;
} else {
/* Cannot retrieve first entry */
error = 1;
dirent_set_errno (ENOENT);
}
} else {
/* Cannot retrieve full path name */
dirent_set_errno (ENOENT);
error = 1;
}
} else {
/* Cannot allocate memory for search pattern */
error = 1;
}
} else {
/* Cannot allocate _WDIR structure */
error = 1;
}
/* Clean up in case of error */
if (error && dirp) {
_wclosedir (dirp);
dirp = NULL;
}
return dirp;
}
/*
* Close directory stream opened by opendir() function. This invalidates the
* DIR structure as well as any directory entry read previously by
* _wreaddir().
*/
static int
_wclosedir(
_WDIR *dirp)
{
int ok;
if (dirp) {
/* Release search handle */
if (dirp->handle != INVALID_HANDLE_VALUE) {
FindClose (dirp->handle);
dirp->handle = INVALID_HANDLE_VALUE;
}
/* Release search pattern */
if (dirp->patt) {
free (dirp->patt);
dirp->patt = NULL;
}
/* Release directory structure */
free (dirp);
ok = /*success*/0;
} else {
/* Invalid directory stream */
dirent_set_errno (EBADF);
ok = /*failure*/-1;
}
return ok;
}
/* Get first directory entry (internal) */
static WIN32_FIND_DATAW*
dirent_first(
_WDIR *dirp)
{
WIN32_FIND_DATAW *datap;
/* Open directory and retrieve the first entry */
dirp->handle = FindFirstFileExW(
dirp->patt, FindExInfoStandard, &dirp->data,
FindExSearchNameMatch, NULL, 0);
if (dirp->handle != INVALID_HANDLE_VALUE) {
/* a directory entry is now waiting in memory */
datap = &dirp->data;
dirp->cached = 1;
} else {
/* Failed to re-open directory: no directory entry in memory */
dirp->cached = 0;
datap = NULL;
}
return datap;
}
/*
* Get next directory entry (internal).
*
* Returns
*/
static WIN32_FIND_DATAW*
dirent_next(
_WDIR *dirp)
{
WIN32_FIND_DATAW *p;
/* Get next directory entry */
if (dirp->cached != 0) {
/* A valid directory entry already in memory */
p = &dirp->data;
dirp->cached = 0;
} else if (dirp->handle != INVALID_HANDLE_VALUE) {
/* Get the next directory entry from stream */
if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
/* Got a file */
p = &dirp->data;
} else {
/* The very last entry has been processed or an error occurred */
FindClose (dirp->handle);
dirp->handle = INVALID_HANDLE_VALUE;
p = NULL;
}
} else {
/* End of directory stream reached */
p = NULL;
}
return p;
}
/*
* Open directory stream using plain old C-string.
*/
static DIR*
opendir(
const char *dirname)
{
struct DIR *dirp;
int error;
/* Must have directory name */
if (dirname == NULL || dirname[0] == '\0') {
dirent_set_errno (ENOENT);
return NULL;
}
/* Allocate memory for DIR structure */
dirp = (DIR*) malloc (sizeof (struct DIR));
if (dirp) {
wchar_t wname[PATH_MAX + 1];
size_t n;
/* Convert directory name to wide-character string */
error = dirent_mbstowcs_s(
&n, wname, PATH_MAX + 1, dirname, PATH_MAX + 1);
if (!error) {
/* Open directory stream using wide-character name */
dirp->wdirp = _wopendir (wname);
if (dirp->wdirp) {
/* Directory stream opened */
error = 0;
} else {
/* Failed to open directory stream */
error = 1;
}
} else {
/*
* Cannot convert file name to wide-character string. This
* occurs if the string contains invalid multi-byte sequences or
* the output buffer is too small to contain the resulting
* string.
*/
error = 1;
}
} else {
/* Cannot allocate DIR structure */
error = 1;
}
/* Clean up in case of error */
if (error && dirp) {
free (dirp);
dirp = NULL;
}
return dirp;
}
/*
* Read next directory entry.
*/
static struct dirent*
readdir(
DIR *dirp)
{
struct dirent *entry;
/*
* Read directory entry to buffer. We can safely ignore the return value
* as entry will be set to NULL in case of error.
*/
(void) readdir_r (dirp, &dirp->ent, &entry);
/* Return pointer to statically allocated directory entry */
return entry;
}
/*
* Read next directory entry into called-allocated buffer.
*
* Returns zero on success. If the end of directory stream is reached, then
* sets result to NULL and returns zero.
*/
static int
readdir_r(
DIR *dirp,
struct dirent *entry,
struct dirent **result)
{
WIN32_FIND_DATAW *datap;
/* Read next directory entry */
datap = dirent_next (dirp->wdirp);
if (datap) {
size_t n;
int error;
/* Attempt to convert file name to multi-byte string */
error = dirent_wcstombs_s(
&n, entry->d_name, PATH_MAX + 1, datap->cFileName, PATH_MAX + 1);
/*
* If the file name cannot be represented by a multi-byte string,
* then attempt to use old 8+3 file name. This allows traditional
* Unix-code to access some file names despite of unicode
* characters, although file names may seem unfamiliar to the user.
*
* Be ware that the code below cannot come up with a short file
* name unless the file system provides one. At least
* VirtualBox shared folders fail to do this.
*/
if (error && datap->cAlternateFileName[0] != '\0') {
error = dirent_wcstombs_s(
&n, entry->d_name, PATH_MAX + 1,
datap->cAlternateFileName, PATH_MAX + 1);
}
if (!error) {
DWORD attr;
/* Length of file name excluding zero terminator */
entry->d_namlen = n - 1;
/* File attributes */
attr = datap->dwFileAttributes;
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
entry->d_type = DT_CHR;
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
entry->d_type = DT_DIR;
} else {
entry->d_type = DT_REG;
}
/* Reset dummy fields */
entry->d_ino = 0;
entry->d_off = 0;
entry->d_reclen = sizeof (struct dirent);
} else {
/*
* Cannot convert file name to multi-byte string so construct
* an erroneous directory entry and return that. Note that
* we cannot return NULL as that would stop the processing
* of directory entries completely.
*/
entry->d_name[0] = '?';
entry->d_name[1] = '\0';
entry->d_namlen = 1;
entry->d_type = DT_UNKNOWN;
entry->d_ino = 0;
entry->d_off = -1;
entry->d_reclen = 0;
}
/* Return pointer to directory entry */
*result = entry;
} else {
/* No more directory entries */
*result = NULL;
}
return /*OK*/0;
}
/*
* Close directory stream.
*/
static int
closedir(
DIR *dirp)
{
int ok;
if (dirp) {
/* Close wide-character directory stream */
ok = _wclosedir (dirp->wdirp);
dirp->wdirp = NULL;
/* Release multi-byte character version */
free (dirp);
} else {
/* Invalid directory stream */
dirent_set_errno (EBADF);
ok = /*failure*/-1;
}
return ok;
}
/* Convert multi-byte string to wide character string */
static int
dirent_mbstowcs_s(
size_t *pReturnValue,
wchar_t *wcstr,
size_t sizeInWords,
const char *mbstr,
size_t count)
{
int error;
#if defined(_MSC_VER) && _MSC_VER >= 1400
/* Microsoft Visual Studio 2005 or later */
error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
#else
/* Older Visual Studio or non-Microsoft compiler */
size_t n;
/* Convert to wide-character string (or count characters) */
n = mbstowcs (wcstr, mbstr, sizeInWords);
if (!wcstr || n < count) {
/* Zero-terminate output buffer */
if (wcstr && sizeInWords) {
if (n >= sizeInWords) {
n = sizeInWords - 1;
}
wcstr[n] = 0;
}
/* Length of resulting multi-byte string WITH zero terminator */
if (pReturnValue) {
*pReturnValue = n + 1;
}
/* Success */
error = 0;
} else {
/* Could not convert string */
error = 1;
}
#endif
return error;
}
/* Convert wide-character string to multi-byte string */
static int
dirent_wcstombs_s(
size_t *pReturnValue,
char *mbstr,
size_t sizeInBytes, /* max size of mbstr */
const wchar_t *wcstr,
size_t count)
{
int error;
#if defined(_MSC_VER) && _MSC_VER >= 1400
/* Microsoft Visual Studio 2005 or later */
error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
#else
/* Older Visual Studio or non-Microsoft compiler */
size_t n;
/* Convert to multi-byte string (or count the number of bytes needed) */
n = wcstombs (mbstr, wcstr, sizeInBytes);
if (!mbstr || n < count) {
/* Zero-terminate output buffer */
if (mbstr && sizeInBytes) {
if (n >= sizeInBytes) {
n = sizeInBytes - 1;
}
mbstr[n] = '\0';
}
/* Length of resulting multi-bytes string WITH zero-terminator */
if (pReturnValue) {
*pReturnValue = n + 1;
}
/* Success */
error = 0;
} else {
/* Cannot convert string */
error = 1;
}
#endif
return error;
}
/* Set errno variable */
static void
dirent_set_errno(
int error)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
/* Microsoft Visual Studio 2005 and later */
_set_errno (error);
#else
/* Non-Microsoft compiler or older Microsoft compiler */
errno = error;
#endif
}
#ifdef __cplusplus
}
#endif
#endif /*DIRENT_H*/

View File

@ -4,16 +4,14 @@
#include <stdlib.h> #include <stdlib.h>
#define warnx(...) do { \ #define warnx(...) do { \
fprintf (stderr, __VA_ARGS__); \ fprintf (stderr, __VA_ARGS__); \
fprintf (stderr, "\n"); \ fprintf (stderr, "\n"); \
} while (0) } while (0)
#define errx(code, ...) do { \ #define errx(code, ...) do { \
fprintf (stderr, __VA_ARGS__); \ fprintf (stderr, __VA_ARGS__); \
fprintf (stderr, "\n"); \ fprintf (stderr, "\n"); \
exit (code); \ exit (code); \
} while (0) } while (0)
#define err errx
#endif /* !_ERR_H_ */ #endif /* !_ERR_H_ */

View File

@ -1,106 +0,0 @@
#include "getopt.h" // make sure you construct the header file as dictated above
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <string.h>
#include <stdio.h>
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
/*
* getopt --
* Parse argc/argv argument vector.
*/
int getopt(int nargc, char * const nargv[], const char *ostr)
{
static char *place = EMSG; /* option letter processing */
const char *oli; /* option letter list index */
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = EMSG;
return (-1);
}
if (place[1] && *++place == '-') { /* found "--" */
++optind;
place = EMSG;
return (-1);
}
} /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, optopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means -1.
*/
if (optopt == (int)'-')
return (-1);
if (!*place)
++optind;
if (opterr && *ostr != ':')
(void)printf("illegal option -- %c\n", optopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
}
else { /* need an argument */
if (*place) /* no white space */
optarg = place;
else if (nargc <= ++optind) { /* no arg */
place = EMSG;
if (*ostr == ':')
return (BADARG);
if (opterr)
(void)printf("option requires an argument -- %c\n", optopt);
return (BADCH);
}
else /* white space */
optarg = nargv[optind];
place = EMSG;
++optind;
}
return (optopt); /* dump back option letter */
}

View File

@ -1,13 +0,0 @@
#ifndef GETOPT_H
#define GETOPT_H
extern int opterr; /* if error message should be printed */
extern int optind; /* index into parent argv vector */
extern int optopt; /* character checked for validity */
extern int optreset; /* reset getopt */
extern char *optarg; /* argument associated with option */
int getopt(int nargc, char * const nargv[], const char *ostr);
#endif

View File

@ -1,4 +0,0 @@
SUBDIRS = buses .
EXTRA_DIST = \
log-internal.c

View File

@ -1,2 +0,0 @@
EXTRA_DIST = \
uart.c

View File

@ -1,284 +0,0 @@
/*-
* Free/Libre Near Field Communication (NFC) library
*
* Libnfc historical contributors:
* Copyright (C) 2009 Roel Verdult
* Copyright (C) 2009-2013 Romuald Conty
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
*
* 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 uart.c
* @brief Windows UART driver
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif // HAVE_CONFIG_H
#include "uart.h"
#include <nfc/nfc.h>
#include "nfc-internal.h"
#include <inttypes.h>
#include "log.h"
#define LOG_GROUP NFC_LOG_GROUP_COM
#define LOG_CATEGORY "libnfc.bus.uart_win32"
// Handle platform specific includes
#include "contrib/windows.h"
#define delay_ms( X ) Sleep( X )
struct serial_port_windows {
HANDLE hPort; // Serial port handle
DCB dcb; // Device control settings
COMMTIMEOUTS ct; // Serial port time-out configuration
};
serial_port
uart_open(const char *pcPortName)
{
char acPortName[255];
struct serial_port_windows *sp = malloc(sizeof(struct serial_port_windows));
if (sp == 0)
return INVALID_SERIAL_PORT;
// Copy the input "com?" to "\\.\COM?" format
sprintf(acPortName, "\\\\.\\%s", pcPortName);
_strupr(acPortName);
// Try to open the serial port
sp->hPort = CreateFileA(acPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (sp->hPort == INVALID_HANDLE_VALUE) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
// Prepare the device control
memset(&sp->dcb, 0, sizeof(DCB));
sp->dcb.DCBlength = sizeof(DCB);
if (!BuildCommDCBA("baud=9600 data=8 parity=N stop=1", &sp->dcb)) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
// Update the active serial port
if (!SetCommState(sp->hPort, &sp->dcb)) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
sp->ct.ReadIntervalTimeout = 30;
sp->ct.ReadTotalTimeoutMultiplier = 0;
sp->ct.ReadTotalTimeoutConstant = 30;
sp->ct.WriteTotalTimeoutMultiplier = 30;
sp->ct.WriteTotalTimeoutConstant = 0;
if (!SetCommTimeouts(sp->hPort, &sp->ct)) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
return sp;
}
void
uart_close(const serial_port sp)
{
if (((struct serial_port_windows *) sp)->hPort != INVALID_HANDLE_VALUE) {
CloseHandle(((struct serial_port_windows *) sp)->hPort);
}
free(sp);
}
void
uart_flush_input(const serial_port sp, bool wait)
{
PurgeComm(((struct serial_port_windows *) sp)->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
}
void
uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
{
struct serial_port_windows *spw;
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Serial port speed requested to be set to %d baud.", uiPortSpeed);
// Set port speed (Input and Output)
switch (uiPortSpeed) {
case 9600:
case 19200:
case 38400:
case 57600:
case 115200:
case 230400:
case 460800:
break;
default:
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to set serial port speed to %d baud. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200, 230400 or 460800.", uiPortSpeed);
return;
};
spw = (struct serial_port_windows *) sp;
// Set baud rate
spw->dcb.BaudRate = uiPortSpeed;
if (!SetCommState(spw->hPort, &spw->dcb)) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to apply new speed settings.");
return;
}
PurgeComm(spw->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
}
uint32_t
uart_get_speed(const serial_port sp)
{
const struct serial_port_windows *spw = (struct serial_port_windows *) sp;
if (!GetCommState(spw->hPort, (serial_port) & spw->dcb))
return spw->dcb.BaudRate;
return 0;
}
int
uart_receive(serial_port sp, uint8_t *pbtRx, const size_t szRx, void *abort_p, int timeout)
{
DWORD dwBytesToGet = (DWORD)szRx;
DWORD dwBytesReceived = 0;
DWORD dwTotalBytesReceived = 0;
BOOL res;
// XXX Put this part into uart_win32_timeouts () ?
DWORD timeout_ms = timeout;
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = timeout_ms;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = timeout_ms;
if (!SetCommTimeouts(((struct serial_port_windows *) sp)->hPort, &timeouts)) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to apply new timeout settings.");
return NFC_EIO;
}
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Timeouts are set to %lu ms", timeout_ms);
// TODO Enhance the reception method
// - According to MSDN, it could be better to implement nfc_abort_command() mechanism using Cancello()
volatile bool *abort_flag_p = (volatile bool *)abort_p;
do {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "ReadFile");
res = ReadFile(((struct serial_port_windows *) sp)->hPort, pbtRx + dwTotalBytesReceived,
dwBytesToGet,
&dwBytesReceived, NULL);
dwTotalBytesReceived += dwBytesReceived;
if (!res) {
DWORD err = GetLastError();
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "ReadFile error: %lu", err);
return NFC_EIO;
} else if (dwBytesReceived == 0) {
return NFC_ETIMEOUT;
}
if (((DWORD)szRx) > dwTotalBytesReceived) {
dwBytesToGet -= dwBytesReceived;
}
if (abort_flag_p != NULL && (*abort_flag_p) && dwTotalBytesReceived == 0) {
return NFC_EOPABORTED;
}
} while (((DWORD)szRx) > dwTotalBytesReceived);
LOG_HEX(LOG_GROUP, "RX", pbtRx, szRx);
return (dwTotalBytesReceived == (DWORD) szRx) ? 0 : NFC_EIO;
}
int
uart_send(serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout)
{
DWORD dwTxLen = 0;
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = timeout;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = timeout;
if (!SetCommTimeouts(((struct serial_port_windows *) sp)->hPort, &timeouts)) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to apply new timeout settings.");
return NFC_EIO;
}
LOG_HEX(LOG_GROUP, "TX", pbtTx, szTx);
if (!WriteFile(((struct serial_port_windows *) sp)->hPort, pbtTx, szTx, &dwTxLen, NULL)) {
return NFC_EIO;
}
if (!dwTxLen)
return NFC_EIO;
return 0;
}
BOOL is_port_available(int nPort)
{
TCHAR szPort[15];
COMMCONFIG cc;
DWORD dwCCSize;
sprintf(szPort, "COM%d", nPort);
// Check if this port is available
dwCCSize = sizeof(cc);
return GetDefaultCommConfig(szPort, &cc, &dwCCSize);
}
// Path to the serial port is OS-dependant.
// Try to guess what we should use.
#define MAX_SERIAL_PORT_WIN 255
char **
uart_list_ports(void)
{
char **availablePorts = malloc((1 + MAX_SERIAL_PORT_WIN) * sizeof(char *));
if (!availablePorts) {
perror("malloc");
return availablePorts;
}
int curIndex = 0;
int i;
for (i = 1; i <= MAX_SERIAL_PORT_WIN; i++) {
if (is_port_available(i)) {
availablePorts[curIndex] = (char *)malloc(10);
if (!availablePorts[curIndex]) {
perror("malloc");
break;
}
sprintf(availablePorts[curIndex], "COM%d", i);
// printf("found candidate port: %s\n", availablePorts[curIndex]);
curIndex++;
}
}
availablePorts[curIndex] = NULL;
return availablePorts;
}

View File

@ -1,61 +0,0 @@
/*-
* Free/Libre Near Field Communication (NFC) library
*
* Libnfc historical contributors:
* Copyright (C) 2009 Roel Verdult
* Copyright (C) 2009-2013 Romuald Conty
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
* Copyright (C) 2013 Alex Lian
*
* 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/>
*/
#include "log-internal.h"
#include <stdio.h>
#include <stdarg.h>
#include <strsafe.h>
static void
log_output_debug(const char *format, va_list args)
{
char buffer[1024];
HRESULT hr = StringCbVPrintf(buffer, sizeof(buffer), format, args);
// Spew what we got, even if the buffer is not sized large enough
if ((STRSAFE_E_INSUFFICIENT_BUFFER == hr) || (S_OK == hr))
OutputDebugString(buffer);
}
void
log_vput_internal(const char *format, va_list args)
{
vfprintf(stderr, format, args);
// Additional windows output to the debug window for debugging purposes
log_output_debug(format, args);
}
void
log_put_internal(const char *format, ...)
{
va_list va;
va_start(va, format);
vfprintf(stderr, format, va);
// Additional windows output to the debug window for debugging purposes
log_output_debug(format, va);
va_end(va);
}

View File

@ -1,57 +0,0 @@
LIBRARY libnfc
VERSION 1.7
EXPORTS
nfc_init
nfc_exit
nfc_register_driver
nfc_open
nfc_close
nfc_abort_command
nfc_list_devices
nfc_idle
nfc_initiator_init
nfc_initiator_init_secure_element
nfc_initiator_select_passive_target
nfc_initiator_list_passive_targets
nfc_initiator_poll_target
nfc_initiator_select_dep_target
nfc_initiator_poll_dep_target
nfc_initiator_deselect_target
nfc_initiator_transceive_bytes
nfc_initiator_transceive_bits
nfc_initiator_transceive_bytes_timed
nfc_initiator_transceive_bits_timed
nfc_initiator_target_is_present
nfc_target_init
nfc_target_send_bytes
nfc_target_receive_bytes
nfc_target_send_bits
nfc_target_receive_bits
nfc_strerror
nfc_strerror_r
nfc_perror
nfc_device_get_last_error
nfc_device_get_name
nfc_device_get_connstring
nfc_device_get_supported_modulation
nfc_device_get_supported_baud_rate
nfc_device_get_supported_baud_rate_target_mode
nfc_device_set_property_int
nfc_device_set_property_bool
nfc_emulate_target
iso14443a_crc
iso14443a_crc_append
iso14443b_crc
iso14443b_crc_append
iso14443a_locate_historical_bytes
nfc_free
nfc_version
nfc_device_get_information_about
str_nfc_modulation_type
str_nfc_baud_rate
str_nfc_target
pn53x_transceive
pn532_SAMConfiguration
pn53x_read_register
pn53x_write_register

View File

@ -1,57 +0,0 @@
LIBRARY nfc
VERSION 1.7
EXPORTS
nfc_init
nfc_exit
nfc_register_driver
nfc_open
nfc_close
nfc_abort_command
nfc_list_devices
nfc_idle
nfc_initiator_init
nfc_initiator_init_secure_element
nfc_initiator_select_passive_target
nfc_initiator_list_passive_targets
nfc_initiator_poll_target
nfc_initiator_select_dep_target
nfc_initiator_poll_dep_target
nfc_initiator_deselect_target
nfc_initiator_transceive_bytes
nfc_initiator_transceive_bits
nfc_initiator_transceive_bytes_timed
nfc_initiator_transceive_bits_timed
nfc_initiator_target_is_present
nfc_target_init
nfc_target_send_bytes
nfc_target_receive_bytes
nfc_target_send_bits
nfc_target_receive_bits
nfc_strerror
nfc_strerror_r
nfc_perror
nfc_device_get_last_error
nfc_device_get_name
nfc_device_get_connstring
nfc_device_get_supported_modulation
nfc_device_get_supported_baud_rate
nfc_device_get_supported_baud_rate_target_mode
nfc_device_set_property_int
nfc_device_set_property_bool
nfc_emulate_target
iso14443a_crc
iso14443a_crc_append
iso14443b_crc
iso14443b_crc_append
iso14443a_locate_historical_bytes
nfc_free
nfc_version
nfc_device_get_information_about
str_nfc_modulation_type
str_nfc_baud_rate
str_nfc_target
pn53x_transceive
pn532_SAMConfiguration
pn53x_read_register
pn53x_write_register

View File

@ -0,0 +1,2 @@
"stdint.h" and "inttypes.h" for Microsoft Visual Studio comes from 'msinttypes' project available at:
http://code.google.com/p/msinttypes/

View File

@ -0,0 +1,138 @@
------------------------------------------------------------------------
r26 | 2009-10-02 13:36:47 +0400 | 2 lines
[Issue 5] Change <stdint.h> to "stdint.h" to let compiler search for it in local directory.
------------------------------------------------------------------------
r25 | 2009-09-17 23:46:49 +0400 | 2 lines
[Issue 4] Fix incorrect int8_t behaviour if compiled with /J flag.
------------------------------------------------------------------------
r24 | 2009-05-13 14:53:48 +0400 | 2 lines
Forgot about #ifdef __cplusplus guard around 'extern "C"', so inclusion to C files has been broken.
------------------------------------------------------------------------
r23 | 2009-05-12 01:27:45 +0400 | 3 lines
[Issue 2] Always wrap <wcharîàž with external "C" {}.
It turns out that not only Visual Studio 6 requires this, but also newer versions when compiling for ARM.
------------------------------------------------------------------------
r22 | 2009-05-11 22:22:15 +0400 | 3 lines
[Issue 3] Visual Studio 6 and Embedded Visual C++ 4 doesn't realize that, e.g. char has the same size as __int8 so we give up on __intX for them.
his should close Issue 3 in issue tracker.
------------------------------------------------------------------------
r21 | 2008-07-17 09:47:22 +0400 | 4 lines
Get rid of these compiler warnings when compiling for 32-bit:
warning C4311: 'type cast' : pointer truncation from 'void *' to 'uintptr_t'
warning C4312: 'type cast' : conversion from 'uintptr_t' to 'const void *' of greater size
------------------------------------------------------------------------
r20 | 2007-10-09 16:54:27 +0400 | 2 lines
Better C99 conformance: macros for format specifiers should only be included in C++ implementations if __STDC_FORMAT_MACROS is defined before <inttypes.h> is included.
------------------------------------------------------------------------
r19 | 2007-07-04 02:14:40 +0400 | 3 lines
Explicitly cast to appropriate type INT8_MIN, INT16_MIN, INT32_MIN and INT64_MIN constants.
Due to their unusual definition in Visual Studio headers (-_Ix_MAX-1) they are propagated to int and thus do not have expected type, causing VS6 strict compiler to claim about type inconsistency.
------------------------------------------------------------------------
r18 | 2007-06-26 16:53:23 +0400 | 2 lines
Better handling of (U)INTx_C macros - now they generate constants of exact width.
------------------------------------------------------------------------
r17 | 2007-03-29 20:16:14 +0400 | 2 lines
Fix typo: Miscrosoft -> Microsoft.
------------------------------------------------------------------------
r16 | 2007-02-24 17:32:58 +0300 | 4 lines
Remove <BaseTsd.h> include, as it is not present in Visual Studio 2005 Epxress Edition and required only for INT_PTR and UINT_PTR types.
'intptr_t' and 'uintptr_t' types now defined explicitly with #ifdef _WIN64.
------------------------------------------------------------------------
r15 | 2007-02-11 20:53:05 +0300 | 2 lines
More correct fix for compilation under VS6.
------------------------------------------------------------------------
r14 | 2007-02-11 20:04:32 +0300 | 2 lines
Bugfix: fix compiling under VS6, when stdint.h enclosed in 'extern "C" {}'.
------------------------------------------------------------------------
r13 | 2006-12-13 16:53:11 +0300 | 2 lines
Make _inline modifier for imaxdiv default option. Use STATIC_IMAXDIV to make it static.
------------------------------------------------------------------------
r12 | 2006-12-13 16:42:24 +0300 | 2 lines
Error message changed: VC6 supported from now.
------------------------------------------------------------------------
r11 | 2006-12-13 16:39:33 +0300 | 2 lines
All (U)INT* types changed to (unsigned) __int*. This should make stdint.h compatible with VC6.
------------------------------------------------------------------------
r10 | 2006-12-13 16:20:57 +0300 | 3 lines
Added INLINE_IMAXDIV define switch.
If INLINE_IMAXDIV is defined imaxdiv() have static modifier. If not - it is _inline.
------------------------------------------------------------------------
r9 | 2006-12-13 15:53:52 +0300 | 2 lines
Error message for non-MSC compiler changed.
------------------------------------------------------------------------
r8 | 2006-12-13 12:47:48 +0300 | 2 lines
Added #ifndef for SIZE_MAX (it is defined in limits.h on MSVSC 8).
------------------------------------------------------------------------
r7 | 2006-12-13 01:08:02 +0300 | 2 lines
License chaged to BSD-derivative.
------------------------------------------------------------------------
r6 | 2006-12-13 00:53:20 +0300 | 2 lines
Added <wchar.h> include to avoid warnings when it is included after stdint.h.
------------------------------------------------------------------------
r5 | 2006-12-12 00:58:05 +0300 | 2 lines
BUGFIX: Definitions of INTPTR_MIN, INTPTR_MAX and UINTPTR_MAX for WIN32 and WIN64 was mixed up.
------------------------------------------------------------------------
r4 | 2006-12-12 00:51:55 +0300 | 2 lines
Rise #error if _MSC_VER is not defined. I.e. compiler other then Microsoft Visual C++ is used.
------------------------------------------------------------------------
r3 | 2006-12-11 22:54:14 +0300 | 2 lines
Added <limits.h> include to stdint.h.
------------------------------------------------------------------------
r2 | 2006-12-11 21:39:27 +0300 | 2 lines
Initial check in.
------------------------------------------------------------------------
r1 | 2006-12-11 21:30:23 +0300 | 1 line
Initial directory structure.
------------------------------------------------------------------------

View File

@ -0,0 +1,305 @@
// ISO C9x compliant inttypes.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_INTTYPES_H_ // [
#define _MSC_INTTYPES_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include "stdint.h"
// 7.8 Format conversion of integer types
typedef struct {
intmax_t quot;
intmax_t rem;
} imaxdiv_t;
// 7.8.1 Macros for format specifiers
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
// The fprintf macros for signed integers are:
#define PRId8 "d"
#define PRIi8 "i"
#define PRIdLEAST8 "d"
#define PRIiLEAST8 "i"
#define PRIdFAST8 "d"
#define PRIiFAST8 "i"
#define PRId16 "hd"
#define PRIi16 "hi"
#define PRIdLEAST16 "hd"
#define PRIiLEAST16 "hi"
#define PRIdFAST16 "hd"
#define PRIiFAST16 "hi"
#define PRId32 "I32d"
#define PRIi32 "I32i"
#define PRIdLEAST32 "I32d"
#define PRIiLEAST32 "I32i"
#define PRIdFAST32 "I32d"
#define PRIiFAST32 "I32i"
#define PRId64 "I64d"
#define PRIi64 "I64i"
#define PRIdLEAST64 "I64d"
#define PRIiLEAST64 "I64i"
#define PRIdFAST64 "I64d"
#define PRIiFAST64 "I64i"
#define PRIdMAX "I64d"
#define PRIiMAX "I64i"
#define PRIdPTR "Id"
#define PRIiPTR "Ii"
// The fprintf macros for unsigned integers are:
#define PRIo8 "o"
#define PRIu8 "u"
#define PRIx8 "x"
#define PRIX8 "X"
#define PRIoLEAST8 "o"
#define PRIuLEAST8 "u"
#define PRIxLEAST8 "x"
#define PRIXLEAST8 "X"
#define PRIoFAST8 "o"
#define PRIuFAST8 "u"
#define PRIxFAST8 "x"
#define PRIXFAST8 "X"
#define PRIo16 "ho"
#define PRIu16 "hu"
#define PRIx16 "hx"
#define PRIX16 "hX"
#define PRIoLEAST16 "ho"
#define PRIuLEAST16 "hu"
#define PRIxLEAST16 "hx"
#define PRIXLEAST16 "hX"
#define PRIoFAST16 "ho"
#define PRIuFAST16 "hu"
#define PRIxFAST16 "hx"
#define PRIXFAST16 "hX"
#define PRIo32 "I32o"
#define PRIu32 "I32u"
#define PRIx32 "I32x"
#define PRIX32 "I32X"
#define PRIoLEAST32 "I32o"
#define PRIuLEAST32 "I32u"
#define PRIxLEAST32 "I32x"
#define PRIXLEAST32 "I32X"
#define PRIoFAST32 "I32o"
#define PRIuFAST32 "I32u"
#define PRIxFAST32 "I32x"
#define PRIXFAST32 "I32X"
#define PRIo64 "I64o"
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#define PRIX64 "I64X"
#define PRIoLEAST64 "I64o"
#define PRIuLEAST64 "I64u"
#define PRIxLEAST64 "I64x"
#define PRIXLEAST64 "I64X"
#define PRIoFAST64 "I64o"
#define PRIuFAST64 "I64u"
#define PRIxFAST64 "I64x"
#define PRIXFAST64 "I64X"
#define PRIoMAX "I64o"
#define PRIuMAX "I64u"
#define PRIxMAX "I64x"
#define PRIXMAX "I64X"
#define PRIoPTR "Io"
#define PRIuPTR "Iu"
#define PRIxPTR "Ix"
#define PRIXPTR "IX"
// The fscanf macros for signed integers are:
#define SCNd8 "d"
#define SCNi8 "i"
#define SCNdLEAST8 "d"
#define SCNiLEAST8 "i"
#define SCNdFAST8 "d"
#define SCNiFAST8 "i"
#define SCNd16 "hd"
#define SCNi16 "hi"
#define SCNdLEAST16 "hd"
#define SCNiLEAST16 "hi"
#define SCNdFAST16 "hd"
#define SCNiFAST16 "hi"
#define SCNd32 "ld"
#define SCNi32 "li"
#define SCNdLEAST32 "ld"
#define SCNiLEAST32 "li"
#define SCNdFAST32 "ld"
#define SCNiFAST32 "li"
#define SCNd64 "I64d"
#define SCNi64 "I64i"
#define SCNdLEAST64 "I64d"
#define SCNiLEAST64 "I64i"
#define SCNdFAST64 "I64d"
#define SCNiFAST64 "I64i"
#define SCNdMAX "I64d"
#define SCNiMAX "I64i"
#ifdef _WIN64 // [
# define SCNdPTR "I64d"
# define SCNiPTR "I64i"
#else // _WIN64 ][
# define SCNdPTR "ld"
# define SCNiPTR "li"
#endif // _WIN64 ]
// The fscanf macros for unsigned integers are:
#define SCNo8 "o"
#define SCNu8 "u"
#define SCNx8 "x"
#define SCNX8 "X"
#define SCNoLEAST8 "o"
#define SCNuLEAST8 "u"
#define SCNxLEAST8 "x"
#define SCNXLEAST8 "X"
#define SCNoFAST8 "o"
#define SCNuFAST8 "u"
#define SCNxFAST8 "x"
#define SCNXFAST8 "X"
#define SCNo16 "ho"
#define SCNu16 "hu"
#define SCNx16 "hx"
#define SCNX16 "hX"
#define SCNoLEAST16 "ho"
#define SCNuLEAST16 "hu"
#define SCNxLEAST16 "hx"
#define SCNXLEAST16 "hX"
#define SCNoFAST16 "ho"
#define SCNuFAST16 "hu"
#define SCNxFAST16 "hx"
#define SCNXFAST16 "hX"
#define SCNo32 "lo"
#define SCNu32 "lu"
#define SCNx32 "lx"
#define SCNX32 "lX"
#define SCNoLEAST32 "lo"
#define SCNuLEAST32 "lu"
#define SCNxLEAST32 "lx"
#define SCNXLEAST32 "lX"
#define SCNoFAST32 "lo"
#define SCNuFAST32 "lu"
#define SCNxFAST32 "lx"
#define SCNXFAST32 "lX"
#define SCNo64 "I64o"
#define SCNu64 "I64u"
#define SCNx64 "I64x"
#define SCNX64 "I64X"
#define SCNoLEAST64 "I64o"
#define SCNuLEAST64 "I64u"
#define SCNxLEAST64 "I64x"
#define SCNXLEAST64 "I64X"
#define SCNoFAST64 "I64o"
#define SCNuFAST64 "I64u"
#define SCNxFAST64 "I64x"
#define SCNXFAST64 "I64X"
#define SCNoMAX "I64o"
#define SCNuMAX "I64u"
#define SCNxMAX "I64x"
#define SCNXMAX "I64X"
#ifdef _WIN64 // [
# define SCNoPTR "I64o"
# define SCNuPTR "I64u"
# define SCNxPTR "I64x"
# define SCNXPTR "I64X"
#else // _WIN64 ][
# define SCNoPTR "lo"
# define SCNuPTR "lu"
# define SCNxPTR "lx"
# define SCNXPTR "lX"
#endif // _WIN64 ]
#endif // __STDC_FORMAT_MACROS ]
// 7.8.2 Functions for greatest-width integer types
// 7.8.2.1 The imaxabs function
#define imaxabs _abs64
// 7.8.2.2 The imaxdiv function
// This is modified version of div() function from Microsoft's div.c found
// in %MSVC.NET%\crt\src\div.c
#ifdef STATIC_IMAXDIV // [
static
#else // STATIC_IMAXDIV ][
_inline
#endif // STATIC_IMAXDIV ]
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
{
imaxdiv_t result;
result.quot = numer / denom;
result.rem = numer % denom;
if (numer < 0 && result.rem > 0) {
// did division wrong; must fix up
++result.quot;
result.rem -= denom;
}
return result;
}
// 7.8.2.3 The strtoimax and strtoumax functions
#define strtoimax _strtoi64
#define strtoumax _strtoui64
// 7.8.2.4 The wcstoimax and wcstoumax functions
#define wcstoimax _wcstoi64
#define wcstoumax _wcstoui64
#endif // _MSC_INTTYPES_H_ ]

View File

@ -1,35 +1,39 @@
/*- /**
* Free/Libre Near Field Communication (NFC) library * Public platform independent Near Field Communication (NFC) library
* *
* Libnfc historical contributors: * Copyright (C) 2009, Roel Verdult
* Copyright (C) 2019 Frank Morgner *
* See AUTHORS file for a more comprehensive list of contributors. * This program is free software: you can redistribute it and/or modify it
* Additional contributors of this file: * 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
* This program is free software: you can redistribute it and/or modify it * option) any later version.
* 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 * This program is distributed in the hope that it will be useful, but WITHOUT
* option) any later version. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* This program is distributed in the hope that it will be useful, but WITHOUT * more details.
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * You should have received a copy of the GNU Lesser General Public License
* more details. * along with this program. If not, see <http://www.gnu.org/licenses/>
* *
* 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 stdbool.h
*/ * @brief standard boolean functionality
*
/** * Adds support for the beloved "bool" type ;)
* @file pcsc.h */
* @brief Driver for non-ACR122 devices (behind PC/SC daemon)
*/ #ifndef _STDBOOL_H_
#define _STDBOOL_H_
#ifndef __NFC_DRIVER_PCSC_H__
#define __NFC_DRIVER_PCSC_H__ #define __bool_true_false_are_defined 1
#include <nfc/nfc-types.h> #ifndef __cplusplus
extern const struct nfc_driver pcsc_driver; #define false 0
#define true 1
#endif // ! __NFC_DRIVER_PCSC_H__ typedef int bool;
#endif // __cplusplus
#endif // _STDBOOL_H_

View File

@ -0,0 +1,247 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2008 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifdef __cplusplus
extern "C" {
#endif
# include <wchar.h>
#ifdef __cplusplus
}
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
#define INTMAX_C INT64_C
#define UINTMAX_C UINT64_C
#endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_STDINT_H_ ]

View File

@ -1,57 +0,0 @@
/*-
* Free/Libre Near Field Communication (NFC) library
*
* Libnfc historical contributors:
* Copyright (C) 2009 Roel Verdult
* Copyright (C) 2009-2013 Romuald Conty
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
* Copyright (C) 2013 Alex Lian
*
* 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 stdlib.c
* @brief Windows System compatibility
*/
// Handle platform specific includes
#include "contrib/windows.h"
//There is no setenv()and unsetenv() in windows,but we can use putenv() instead.
int setenv(const char *name, const char *value, int overwrite)
{
char *env = getenv(name);
if ((env && overwrite) || (!env)) {
char *str[32];
strcpy(str, name);
strcat(str, "=");
strcat(str, value);
return putenv(str);
}
return -1;
}
void unsetenv(const char *name)
{
char *str[32];
strcpy(str, name);
strcat(str, "=");
putenv(str);
}

View File

@ -1,2 +0,0 @@
EXTRA_DIST = \
select.h

View File

@ -1,48 +0,0 @@
/*-
* Free/Libre Near Field Communication (NFC) library
*
* Libnfc historical contributors:
* Copyright (C) 2009 Roel Verdult
* Copyright (C) 2009-2013 Romuald Conty
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
*
* 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 unistd.h
* @brief This file intended to serve as a drop-in replacement for unistd.h on Windows
*/
#ifndef _UNISTD_H_
#define _UNISTD_H_
#include "contrib/windows.h"
// Needed by Sleep() under Windows
# include <winbase.h>
# define sleep(X) Sleep( X * 1000)
// With MinGW, getopt(3) is provided as separate header
#if defined(WIN32) && defined(__GNUC__) /* mingw compiler */
#include <getopt.h>
#endif
#endif /* _UNISTD_H_ */

View File

@ -1,29 +0,0 @@
1 VERSIONINFO
FILEVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,0
PRODUCTVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS 0x00040004L
FILETYPE @RC_FILE_TYPE@
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904e4"
BEGIN
VALUE "Comments", "@RC_COMMENT@\0"
VALUE "CompanyName", "libnfc.org\0"
VALUE "FileDescription", "\0"
VALUE "FileVersion", "@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@.0\0"
VALUE "InternalName", "@RC_INTERNAL_NAME@ @WIN32_MODE@\0"
VALUE "LegalCopyright", "Copyright (C) @CURRENT_YEAR@\0"
VALUE "OriginalFilename", "@RC_ORIGINAL_NAME@\0"
VALUE "ProductName", "@PACKAGE_NAME@ @WIN32_MODE@\0"
VALUE "ProductVersion", "@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@.0\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 1252
END
END

View File

@ -1,21 +1,13 @@
/*- /*-
* Free/Libre Near Field Communication (NFC) library * Public platform independent Near Field Communication (NFC) library
* *
* Libnfc historical contributors: * Copyright (C) 2010, Romuald Conty
* Copyright (C) 2009 Roel Verdult *
* Copyright (C) 2009-2013 Romuald Conty
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
* Copyright (C) 2011 Glenn Ergeerts
*
* This program is free software: you can redistribute it and/or modify it * 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 * 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 * Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. * option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -25,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/> * along with this program. If not, see <http://www.gnu.org/licenses/>
*/ */
/** /**
* @file windows.h * @file windows.h
* @brief Provide some windows related hacks due to lack of POSIX compat * @brief Provide some windows related hacks due to lack of POSIX compat
*/ */
@ -34,31 +26,11 @@
#define __WINDOWS_H__ #define __WINDOWS_H__
# include <windows.h> # include <windows.h>
# include <winerror.h>
# include "win32/err.h"
# if defined (__MINGW32__) # if defined (__MINGW32__)
/* # define snprintf(S, n, F, ...) sprintf(S, F, __VA_ARGS__)
* Cheating here on the snprintf to incorporate the format argument
* into the VA_ARGS. Else we get MinGW errors regarding number of arguments
* if doing a fixed string with no arguments.
*/
# define snprintf(S, n, ...) sprintf(S, __VA_ARGS__)
# define pipe(fds) _pipe(fds, 5000, _O_BINARY)
# define ETIMEDOUT WSAETIMEDOUT
# define ENOTSUP WSAEOPNOTSUPP
# define ECONNABORTED WSAECONNABORTED
# else # else
#ifndef _MSC_VER
# define snprintf sprintf_s # define snprintf sprintf_s
#endif
# define strdup _strdup # define strdup _strdup
# endif # endif
/*
* setenv and unsetenv are not Windows compliant nor implemented in MinGW.
* These declarations get rid of the "implicit declaration warning."
*/
int setenv(const char *name, const char *value, int overwrite);
void unsetenv(const char *name);
#endif #endif

85
debian/changelog vendored Normal file
View File

@ -0,0 +1,85 @@
libnfc (1.4.0-0) unstable; urgency=low
* New upstream release.
-- Romuald Conty <rconty@il4p.fr> Tue, 26 Oct 2010 16:42:42 +0100
libnfc (1.3.9-0) unstable; urgency=low
* New upstream release.
-- Romuald Conty <rconty@il4p.fr> Tue, 31 Aug 2010 14:42:42 +0100
libnfc (1.3.4-0) unstable; urgency=low
* New upstream release.
-- Romuald Conty <rconty@il4p.fr> Wed, 31 Mar 2010 12:42:42 +0100
libnfc (1.3.3-0) unstable; urgency=low
* New upstream release.
-- Romuald Conty <rconty@il4p.fr> Thu, 17 Feb 2010 15:42:42 +0100
libnfc (1.3.2-0) unstable; urgency=low
* New upstream release.
-- Romuald Conty <rconty@il4p.fr> Fri, 29 Jan 2010 15:42:42 +0100
libnfc (1.3.1-0) unstable; urgency=low
* New upstream release.
-- Romuald Conty <rconty@il4p.fr> Mon, 25 Jan 2010 11:42:42 +0100
libnfc (1.3.0-0) unstable; urgency=low
* New upstream release.
-- Romuald Conty <rconty@il4p.fr> Thu, 14 Jan 2010 16:42:42 +0100
libnfc (1.2.1-4) unstable; urgency=low
* Add udev rules for USB PN53x.
-- Romuald Conty <rconty@il4p.fr> Fri, 20 Nov 2009 16:42:42 +0100
libnfc (1.2.1-3) unstable; urgency=low
* Don't use CDBS anymore, should now cross compile.
-- Romuald Conty <rconty@il4p.fr> Thu, 29 Sep 2009 9:42:42 +0100
libnfc (1.2.1-2) unstable; urgency=low
* Add missing dependencies for ACR122 devices (pcscd).
-- Romuald Conty <rconty@il4p.fr> Fri, 23 Sep 2009 16:42:42 +0100
libnfc (1.2.1-1) unstable; urgency=low
* Description have been updated.
* Provided binairies should not be consider as tools but as examples.
-- Romuald Conty <rconty@il4p.fr> Fri, 03 Sep 2009 18:42:42 +0100
libnfc (1.2.1-0) unstable; urgency=low
* New upstream version.
-- Romuald Conty <rconty@il4p.fr> Fri, 24 Jul 2009 16:42:42 +0100
libnfc (1.2.0-0) unstable; urgency=low
* New upstream version.
-- Romuald Conty <rconty@il4p.fr> Thu, 23 Jul 2009 15:42:42 +0100
libnfc (1.1.0-0) unstable; urgency=low
* Initial debian package.
-- Romuald Conty <rconty@il4p.fr> Wed, 22 Apr 2009 10:42:42 +0100

1
debian/compat vendored Normal file
View File

@ -0,0 +1 @@
7

41
debian/control vendored Normal file
View File

@ -0,0 +1,41 @@
Source: libnfc
Section: devel
Priority: optional
Maintainer: Romuald Conty <rconty@il4p.fr>
Build-Depends: debhelper (>= 5.0.37.2), automake, libtool, pkg-config, libusb-dev, libpcsclite-dev
Standards-Version: 3.7.3
Homepage: http://www.libnfc.org/
Package: libnfc0
Architecture: any
Depends: ${shlibs:Depends}, libusb-0.1-4, libpcsclite1 (>= 1.5), libccid (>= 1.3.10), pcscd (>= 1.5)
Description: Near Field Communication (NFC) library
libnfc is a Free Software library for Near Field Communication. Supported NFC hardware
devices are, theorically, all hardware based on the NXP PN531, PN532 or PN533 NFC
controller chip.
Package: libnfc-dev
Architecture: any
Depends: libnfc0, libusb-dev, libpcsclite-dev
Description: Near Field Communication library (development files)
libnfc is a Free Software library for Near Field Communication. Supported NFC hardware
devices are, theorically, all hardware based on the NXP PN531, PN532 or PN533 NFC
controller chip.
Package: libnfc-bin
Architecture: any
Depends: libnfc0
Description: Near Field Communication binaries
Some binaries are provided with libnfc useful for developement (nfc-list, nfc-mfclassic, nfc-mfultralight, etc.).
Package: libnfc-examples
Architecture: any
Depends: libnfc0
Description: Near Field Communication examples
Some examples are provided with libnfc for debugging and/or educational purpose (nfc-anticol, nfc-emulate, etc.).
Package: libnfc-pn53x-examples
Architecture: any
Depends: libnfc0
Description: Near Field Communication examples for PN53x chips only
Some PN53x-only examples are provided with libnfc for debugging and/or educational purpose (pn53x-sam, pn53x-tamashell, etc.).

27
debian/copyright vendored Normal file
View File

@ -0,0 +1,27 @@
This package was debianized by Romuald Conty <romuald.conty@free.fr> on
Wed, 22 Apr 2009 10:42:42 +0100.
It was downloaded from: http://www.libnfc.org/
Copyright (C) 2009 by Roel Verdult <roel@libnfc.org>
License: GNU Lesser General Public License version 3
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
as published by the Free Software Foundation
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
On Debian GNU/Linux systems, the complete text of the GNU General Public
License, version 3, can be found in `/usr/share/common-licenses/LGPL-3'.
The Debian packaging is (C) 2009, Romuald Conty <romuald.conty@free.fr> and
is licensed under the GPL, see `/usr/share/common-licenses/GPL'.

6
debian/libnfc-bin.install vendored Normal file
View File

@ -0,0 +1,6 @@
debian/tmp/usr/bin/nfc-list
debian/tmp/usr/bin/nfc-mfclassic
debian/tmp/usr/bin/nfc-mfultralight
debian/tmp/usr/share/man/man1/nfc-list.1
debian/tmp/usr/share/man/man1/nfc-mfclassic.1
debian/tmp/usr/share/man/man1/nfc-mfultralight.1

3
debian/libnfc-dev.install vendored Normal file
View File

@ -0,0 +1,3 @@
debian/tmp/usr/include/nfc
debian/tmp/usr/lib/libnfc.{a,la,so}
debian/tmp/usr/lib/pkgconfig/libnfc.pc

18
debian/libnfc-examples.install vendored Normal file
View File

@ -0,0 +1,18 @@
debian/tmp/usr/bin/nfc-anticol
debian/tmp/usr/bin/nfc-dep-initiator
debian/tmp/usr/bin/nfc-dep-target
debian/tmp/usr/bin/nfc-emulate-forum-tag4
debian/tmp/usr/bin/nfc-emulate-tag
debian/tmp/usr/bin/nfc-emulate-uid
debian/tmp/usr/bin/nfc-poll
debian/tmp/usr/bin/nfc-relay
debian/tmp/usr/bin/nfc-relay-picc
debian/tmp/usr/share/man/man1/nfc-anticol.1
debian/tmp/usr/share/man/man1/nfc-dep-initiator.1
debian/tmp/usr/share/man/man1/nfc-dep-target.1
debian/tmp/usr/share/man/man1/nfc-emulate-forum-tag4.1
debian/tmp/usr/share/man/man1/nfc-emulate-tag.1
debian/tmp/usr/share/man/man1/nfc-emulate-uid.1
debian/tmp/usr/share/man/man1/nfc-poll.1
debian/tmp/usr/share/man/man1/nfc-relay-picc.1
debian/tmp/usr/share/man/man1/nfc-relay.1

3
debian/libnfc-pn53x-examples.install vendored Normal file
View File

@ -0,0 +1,3 @@
debian/tmp/usr/bin/pn53x-*
debian/tmp/usr/share/man/man1/pn53x-*
examples/pn53x-tamashell-scripts/* usr/share/doc/libnfc-pn53x-examples/scripts

2
debian/libnfc0.install vendored Normal file
View File

@ -0,0 +1,2 @@
debian/tmp/usr/lib/libnfc.so.*
pn53x.rules etc/udev/rules.d/

117
debian/rules vendored Executable file
View File

@ -0,0 +1,117 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# These are used for cross-compiling and for saving the configure script
# from having to guess our platform (since we know it already)
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE))
CROSS= --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE)
CROSS_CFLAGS=-I/usr/$(DEB_HOST_GNU_TYPE)/include -I/usr/$(DEB_HOST_GNU_TYPE)/usr/include
LDFLAGS=-L/usr/$(DEB_HOST_GNU_TYPE)/lib -L/usr/$(DEB_HOST_GNU_TYPE)/usr/lib
MAKE_LDFLAGS=-inst-prefix-dir /usr/$(DEB_HOST_GNU_TYPE) -Wl,-rpath-link /usr/$(DEB_HOST_GNU_TYPE)/lib -Wl,-rpath-link /usr/$(DEB_HOST_GNU_TYPE)/usr/lib
DH_STRIP=
DH_SHLIBDEPS=
else
CROSS= --build $(DEB_BUILD_GNU_TYPE)
DH_STRIP=dh_strip
DH_SHLIBDEPS=dh_shlibdeps
endif
# shared library versions, option 1
version=2.0.5
major=2
# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so
#version=`ls src/.libs/lib*.so.* | \
# awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
#major=`ls src/.libs/lib*.so.* | \
# awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
config.status: configure
dh_testdir
# Add here commands to configure the package.
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
cp -f /usr/share/misc/config.sub config.sub
endif
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
cp -f /usr/share/misc/config.guess config.guess
endif
./configure $(CROSS) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info CFLAGS="$(CFLAGS) $(CROSS_CFLAGS)" LDFLAGS="-Wl,-z,defs $(LDFLAGS)"
build: build-stamp
build-stamp: config.status
dh_testdir
# Add here commands to compile the package.
$(MAKE) LDFLAGS="$(MAKE_LDFLAGS) $(LDFLAGS)"
touch $@
clean:
dh_testdir
dh_testroot
rm -f build-stamp
# Add here commands to clean up after the build process.
[ ! -f Makefile ] || $(MAKE) distclean
rm -f config.sub config.guess
dh_clean
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/tmp
$(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installchangelogs ChangeLog
dh_installdocs
dh_installexamples
dh_install
# dh_installmenu
# dh_installdebconf
# dh_installlogrotate
# dh_installemacsen
# dh_installpam
# dh_installmime
# dh_installinit
# dh_installcron
# dh_installinfo
dh_installman
dh_link
$(DH_STRIP)
dh_compress
dh_fixperms
# dh_perl
# dh_python
dh_makeshlibs
dh_installdeb
$(DH_SHLIBDEPS)
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

View File

@ -1,52 +1,24 @@
SET(EXAMPLES-SOURCES SET(EXAMPLES-SOURCES nfc-list nfc-mfclassic nfc-mfultralight nfcip-initiator nfcip-target nfc-anticol nfc-emulate nfc-relay nfc-sam)
nfc-anticol
nfc-dep-initiator
nfc-dep-target
nfc-emulate-forum-tag2
nfc-emulate-tag
nfc-emulate-uid
nfc-mfsetuid
nfc-poll
nfc-relay
nfc-st25tb
pn53x-diagnose
pn53x-sam
pn53x-tamashell
)
# XXX: Examples should not use private API!
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libnfc) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libnfc)
INCLUDE_DIRECTORIES(${LIBUSB_INCLUDE_DIRS} ${PCSC_INCLUDE_DIRS})
LINK_DIRECTORIES(${LIBUSB_LIBRARY_DIRS} ${PCSC_LIBRARY_DIRS})
ADD_LIBRARY(nfc-utils nfc-utils)
ADD_LIBRARY(mifare mifare)
# Examples # Examples
FOREACH(source ${EXAMPLES-SOURCES}) FOREACH(source ${EXAMPLES-SOURCES})
SET (TARGETS ${source}.c) ADD_EXECUTABLE(${source} ${source}.c)
IF(WIN32)
SET(RC_COMMENT "${PACKAGE_NAME} example")
SET(RC_INTERNAL_NAME ${source})
SET(RC_ORIGINAL_NAME ${source}.exe)
# RC_FILE_TYPE: VFT_APP
SET(RC_FILE_TYPE 0x00000001L)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/../windows/${source}.rc @ONLY)
LIST(APPEND TARGETS ${CMAKE_CURRENT_BINARY_DIR}/../windows/${source}.rc)
IF(${source} MATCHES "nfc-st25tb")
LIST(APPEND TARGETS ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/getopt.c)
ENDIF()
ENDIF(WIN32)
ADD_EXECUTABLE(${source} ${TARGETS})
TARGET_LINK_LIBRARIES(${source} nfc) TARGET_LINK_LIBRARIES(${source} nfc)
TARGET_LINK_LIBRARIES(${source} nfcutils) TARGET_LINK_LIBRARIES(${source} nfc-utils)
INSTALL(TARGETS ${source} RUNTIME DESTINATION bin COMPONENT examples) INSTALL(TARGETS ${source} RUNTIME DESTINATION bin COMPONENT examples)
ENDFOREACH(source) ENDFOREACH(source)
#install required libraries TARGET_LINK_LIBRARIES(nfc-mfclassic mifare)
IF(WIN32) TARGET_LINK_LIBRARIES(nfc-mfultralight mifare)
INCLUDE(InstallRequiredSystemLibraries)
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/cmake/FixBundle.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FixBundle.cmake @ONLY)
INSTALL(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/FixBundle.cmake)
ENDIF(WIN32)
IF(NOT WIN32) IF(NOT WIN32)
# Manuals for the examples # Manuals for the examples

View File

@ -1,16 +1,16 @@
SUBDIRS = pn53x-tamashell-scripts
bin_PROGRAMS = \ bin_PROGRAMS = \
nfc-anticol \ nfc-anticol \
nfc-dep-initiator \ nfc-dep-initiator \
nfc-dep-target \ nfc-dep-target \
nfc-emulate-forum-tag2 \ nfc-emulate-forum-tag4 \
nfc-emulate-tag \ nfc-emulate-tag \
nfc-emulate-uid \ nfc-emulate-uid \
nfc-mfsetuid \ nfc-list \
nfc-mfclassic \
nfc-mfultralight \
nfc-poll \ nfc-poll \
nfc-relay \ nfc-relay \
nfc-st25tb \ nfc-relay-picc \
pn53x-diagnose \ pn53x-diagnose \
pn53x-sam pn53x-sam
@ -19,89 +19,90 @@ bin_PROGRAMS += \
pn53x-tamashell pn53x-tamashell
endif endif
check_PROGRAMS = \
quick_start_example1 \
quick_start_example2
# set the include path found by configure # set the include path found by configure
AM_CPPFLAGS = $(all_includes) $(LIBNFC_CFLAGS) INCLUDES= $(all_includes) $(LIBNFC_CFLAGS)
AM_CFLAGS = -I$(top_srcdir)/libnfc -I$(top_srcdir) AM_CFLAGS = -I$(top_srcdir)/libnfc
noinst_HEADERS = mifare.h nfc-utils.h
noinst_LTLIBRARIES = libnfcutils.la
libnfcutils_la_SOURCES = nfc-utils.c
nfc_poll_SOURCES = nfc-poll.c nfc_poll_SOURCES = nfc-poll.c
nfc_poll_LDADD = $(top_builddir)/libnfc/libnfc.la \ nfc_poll_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la libnfcutils.la
nfc_anticol_SOURCES = nfc-anticol.c nfc_anticol_SOURCES = nfc-anticol.c
nfc_anticol_LDADD = $(top_builddir)/libnfc/libnfc.la \ nfc_anticol_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la libnfcutils.la
nfc_list_SOURCES = nfc-list.c
nfc_list_LDADD = $(top_builddir)/libnfc/libnfc.la \
libnfcutils.la
nfc_mfultralight_SOURCES = nfc-mfultralight.c mifare.c mifare.h
nfc_mfultralight_LDADD = $(top_builddir)/libnfc/libnfc.la
nfc_mfclassic_SOURCES = nfc-mfclassic.c mifare.c mifare.h
nfc_mfclassic_LDADD = $(top_builddir)/libnfc/libnfc.la
nfc_relay_SOURCES = nfc-relay.c nfc_relay_SOURCES = nfc-relay.c
nfc_relay_LDADD = $(top_builddir)/libnfc/libnfc.la \ nfc_relay_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la libnfcutils.la
nfc_emulate_forum_tag2_SOURCES = nfc-emulate-forum-tag2.c nfc_relay_picc_SOURCES = nfc-relay-picc.c
nfc_emulate_forum_tag2_LDADD = $(top_builddir)/libnfc/libnfc.la \ nfc_relay_picc_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la libnfcutils.la
nfc_emulate_forum_tag4_SOURCES = nfc-emulate-forum-tag4.c
nfc_emulate_forum_tag4_LDADD = $(top_builddir)/libnfc/libnfc.la \
libnfcutils.la
nfc_emulate_tag_SOURCES = nfc-emulate-tag.c nfc_emulate_tag_SOURCES = nfc-emulate-tag.c
nfc_emulate_tag_LDADD = $(top_builddir)/libnfc/libnfc.la \ nfc_emulate_tag_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la libnfcutils.la
nfc_emulate_uid_SOURCES = nfc-emulate-uid.c nfc_emulate_uid_SOURCES = nfc-emulate-uid.c
nfc_emulate_uid_LDADD = $(top_builddir)/libnfc/libnfc.la \ nfc_emulate_uid_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la libnfcutils.la
nfc_dep_target_SOURCES = nfc-dep-target.c nfc_dep_target_SOURCES = nfc-dep-target.c
nfc_dep_target_LDADD = $(top_builddir)/libnfc/libnfc.la \ nfc_dep_target_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la libnfcutils.la
nfc_dep_initiator_SOURCES = nfc-dep-initiator.c nfc_dep_initiator_SOURCES = nfc-dep-initiator.c
nfc_dep_initiator_LDADD = $(top_builddir)/libnfc/libnfc.la \ nfc_dep_initiator_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la libnfcutils.la
nfc_mfsetuid_SOURCES = nfc-mfsetuid.c
nfc_mfsetuid_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la
nfc_st25tb_SOURCES = nfc-st25tb.c
nfc_st25tb_LDADD = $(top_builddir)/libnfc/libnfc.la
pn53x_diagnose_SOURCES = pn53x-diagnose.c pn53x_diagnose_SOURCES = pn53x-diagnose.c
pn53x_diagnose_LDADD = $(top_builddir)/libnfc/libnfc.la \ pn53x_diagnose_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la libnfcutils.la
pn53x_sam_SOURCES = pn53x-sam.c pn53x_sam_SOURCES = pn53x-sam.c
pn53x_sam_LDADD = $(top_builddir)/libnfc/libnfc.la \ pn53x_sam_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la libnfcutils.la
pn53x_tamashell_SOURCES = pn53x-tamashell.c pn53x_tamashell_SOURCES = pn53x-tamashell.c
pn53x_tamashell_LDADD = $(top_builddir)/libnfc/libnfc.la \ pn53x_tamashell_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la libnfcutils.la
pn53x_tamashell_CFLAGS = @READLINE_INCLUDES@ -I$(top_srcdir)
pn53x_tamashell_LDFLAGS = @READLINE_LIBS@ pn53x_tamashell_LDFLAGS = @READLINE_LIBS@
quick_start_example1_SOURCES = doc/quick_start_example1.c
quick_start_example1_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la
quick_start_example2_SOURCES = doc/quick_start_example2.c
quick_start_example2_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la
dist_man_MANS = \ dist_man_MANS = \
nfc-anticol.1 \ nfc-anticol.1 \
nfc-dep-initiator.1 \ nfc-dep-initiator.1 \
nfc-dep-target.1 \ nfc-dep-target.1 \
nfc-emulate-forum-tag4.1 \
nfc-emulate-tag.1 \ nfc-emulate-tag.1 \
nfc-emulate-uid.1 \ nfc-emulate-uid.1 \
nfc-list.1 \
nfc-mfclassic.1 \
nfc-mfultralight.1 \
nfc-poll.1 \ nfc-poll.1 \
nfc-relay.1 \ nfc-relay.1 \
nfc-mfsetuid.1 \ nfc-relay-picc.1 \
pn53x-diagnose.1 \ pn53x-diagnose.1 \
pn53x-sam.1 \ pn53x-sam.1 \
pn53x-tamashell.1 \ pn53x-tamashell.1
nfc-emulate-forum-tag2.1
EXTRA_DIST = CMakeLists.txt EXTRA_DIST = CMakeLists.txt

View File

@ -1,86 +1,55 @@
/** #ifdef HAVE_CONFIG_H
* @file quick_start_example1.c # include "config.h"
* @brief Quick start example that presents how to use libnfc #endif // HAVE_CONFIG_H
*/
// To compile this simple example:
// $ gcc -o quick_start_example1 quick_start_example1.c -lnfc
#include <stdlib.h> #include <stdlib.h>
#include <nfc/nfc.h> #include <nfc/nfc.h>
#include <nfc/nfc-messages.h>
static void
print_hex(const uint8_t *pbtData, const size_t szBytes)
{
size_t szPos;
for (szPos = 0; szPos < szBytes; szPos++) {
printf("%02x ", pbtData[szPos]);
}
printf("\n");
}
int int
main(int argc, const char *argv[]) main (int argc, const char *argv[])
{ {
nfc_device *pnd; nfc_device_t *pnd;
nfc_target nt; nfc_target_info_t nti;
// Allocate only a pointer to nfc_context
nfc_context *context;
// Initialize libnfc and set the nfc_context
nfc_init(&context);
if (context == NULL) {
printf("Unable to init libnfc (malloc)\n");
exit(EXIT_FAILURE);
}
// Display libnfc version // Display libnfc version
const char *acLibnfcVersion = nfc_version(); const char *acLibnfcVersion = nfc_version ();
(void)argc; printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion);
printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
// Open, using the first available NFC device which can be in order of selection: // Connect using the first available NFC device
// - default device specified using environment variable or pnd = nfc_connect (NULL);
// - first specified device in libnfc.conf (/etc/nfc) or
// - first specified device in device-configuration directory (/etc/nfc/devices.d) or
// - first auto-detected (if feature is not disabled in libnfc.conf) device
pnd = nfc_open(context, NULL);
if (pnd == NULL) { if (pnd == NULL) {
printf("ERROR: %s\n", "Unable to open NFC device."); ERR ("%s", "Unable to connect to NFC device.");
exit(EXIT_FAILURE); return EXIT_FAILURE;
}
// Set opened NFC device to initiator mode
if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init");
exit(EXIT_FAILURE);
} }
// Set connected NFC device to initiator mode
nfc_initiator_init (pnd);
printf("NFC reader: %s opened\n", nfc_device_get_name(pnd)); // 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", pnd->acName);
// Poll for a ISO14443A (MIFARE) tag // Poll for a ISO14443A (MIFARE) tag
const nfc_modulation nmMifare = { const nfc_modulation_t nmMifare = {
.nmt = NMT_ISO14443A, .nmt = NMT_ISO14443A,
.nbr = NBR_106, .nbr = NBR_106,
}; };
if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) > 0) { if (nfc_initiator_select_passive_target (pnd, PM_ISO14443A_106, NULL, 0, &nti)) {
printf("The following (NFC) ISO14443A tag was found:\n"); printf ("The following (NFC) ISO14443A tag was found:\n");
printf(" ATQA (SENS_RES): "); printf (" ATQA (SENS_RES): ");
print_hex(nt.nti.nai.abtAtqa, 2); print_hex (nti.nai.abtAtqa, 2);
printf(" UID (NFCID%c): ", (nt.nti.nai.abtUid[0] == 0x08 ? '3' : '1')); printf (" UID (NFCID%c): ", (nti.nai.abtUid[0] == 0x08 ? '3' : '1'));
print_hex(nt.nti.nai.abtUid, nt.nti.nai.szUidLen); print_hex (nti.nai.abtUid, nti.nai.szUidLen);
printf(" SAK (SEL_RES): "); printf (" SAK (SEL_RES): ");
print_hex(&nt.nti.nai.btSak, 1); print_hex (&nti.nai.btSak, 1);
if (nt.nti.nai.szAtsLen) { if (nti.nai.szAtsLen) {
printf(" ATS (ATR): "); printf (" ATS (ATR): ");
print_hex(nt.nti.nai.abtAts, nt.nti.nai.szAtsLen); print_hex (nti.nai.abtAts, nti.nai.szAtsLen);
} }
} }
// Close NFC device // Disconnect from NFC device
nfc_close(pnd); nfc_disconnect (pnd);
// Release the context return EXIT_SUCCESS;
nfc_exit(context);
exit(EXIT_SUCCESS);
} }

View File

@ -1,83 +0,0 @@
/**
* @file quick_start_example2.c
* @brief Quick start example that presents how to use libnfc
*/
// This is same example as quick_start_example1.c but using
// some helper functions existing in libnfc.
// Those functions are not available yet in a library
// so binary object must be linked statically:
// $ gcc -o quick_start_example2 -lnfc -I../.. quick_start_example2.c ../../utils/nfc-utils.o
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif // HAVE_CONFIG_H
#include <stdlib.h>
#include <nfc/nfc.h>
#include "utils/nfc-utils.h"
int
main(int argc, const char *argv[])
{
nfc_device *pnd;
nfc_target nt;
// Allocate only a pointer to nfc_context
nfc_context *context;
// Initialize libnfc and set the nfc_context
nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
// Display libnfc version
const char *acLibnfcVersion = nfc_version();
(void)argc;
printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
// Open, using the first available NFC device which can be in order of selection:
// - default device specified using environment variable or
// - first specified device in libnfc.conf (/etc/nfc) or
// - first specified device in device-configuration directory (/etc/nfc/devices.d) or
// - first auto-detected (if feature is not disabled in libnfc.conf) device
pnd = nfc_open(context, NULL);
if (pnd == NULL) {
ERR("%s", "Unable to open NFC device.");
exit(EXIT_FAILURE);
}
// Set opened NFC device to initiator mode
if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init");
exit(EXIT_FAILURE);
}
printf("NFC reader: %s opened\n", nfc_device_get_name(pnd));
// Poll for a ISO14443A (MIFARE) tag
const nfc_modulation nmMifare = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) > 0) {
printf("The following (NFC) ISO14443A tag was found:\n");
printf(" ATQA (SENS_RES): ");
print_hex(nt.nti.nai.abtAtqa, 2);
printf(" UID (NFCID%c): ", (nt.nti.nai.abtUid[0] == 0x08 ? '3' : '1'));
print_hex(nt.nti.nai.abtUid, nt.nti.nai.szUidLen);
printf(" SAK (SEL_RES): ");
print_hex(&nt.nti.nai.btSak, 1);
if (nt.nti.nai.szAtsLen) {
printf(" ATS (ATR): ");
print_hex(nt.nti.nai.abtAts, nt.nti.nai.szAtsLen);
}
}
// Close NFC device
nfc_close(pnd);
// Release the context
nfc_exit(context);
exit(EXIT_SUCCESS);
}

View File

@ -1,19 +1,13 @@
/*- /*-
* Free/Libre Near Field Communication (NFC) library * Public platform independent Near Field Communication (NFC) library examples
* *
* Libnfc historical contributors: * Copyright (C) 2009, Roel Verdult
* Copyright (C) 2009 Roel Verdult * Copyright (C) 2010, Romuald Conty, Romain Tartière
* Copyright (C) 2009-2013 Romuald Conty *
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice, * 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright * 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
@ -29,14 +23,11 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* Note that this license only applies on the examples, NFC library itself is under LGPL * Note that this license only applies on the examples, NFC library itself is under LGPL
* *
*/ */
/**
* @file mifare.c
* @brief provide samples structs and functions to manipulate MIFARE Classic and Ultralight tags using libnfc
*/
#include "mifare.h" #include "mifare.h"
#include <string.h> #include <string.h>
@ -51,89 +42,89 @@
* The specified MIFARE command will be executed on the tag. There are different commands possible, they all require the destination block number. * The specified MIFARE command will be executed on the tag. There are different commands possible, they all require the destination block number.
* @note There are three different types of information (Authenticate, Data and Value). * @note There are three different types of information (Authenticate, Data and Value).
* *
* First an authentication must take place using Key A or B. It requires a 48 bit Key (6 bytes) and the UID. * 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. * 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). * 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. * The MIFARE Classic Specification (http://www.nxp.com/acrobat/other/identification/M001053_MF1ICS50_rev5_3.pdf) explains more about this process.
*/ */
bool bool
nfc_initiator_mifare_cmd(nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp) nfc_initiator_mifare_cmd (nfc_device_t * pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param * pmp)
{ {
uint8_t abtRx[265]; byte_t abtRx[265];
size_t szRx;
size_t szParamLen; size_t szParamLen;
uint8_t abtCmd[265]; byte_t abtCmd[265];
//bool bEasyFraming; bool bEasyFraming;
// Make sure we are dealing with a active device
if (!pnd->bActive)
return false;
abtCmd[0] = mc; // The MIFARE Classic command abtCmd[0] = mc; // The MIFARE Classic command
abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff) abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)
switch (mc) { switch (mc) {
// Read and store command have no parameter // Read and store command have no parameter
case MC_READ: case MC_READ:
case MC_STORE: case MC_STORE:
szParamLen = 0; szParamLen = 0;
break; break;
// Authenticate command // Authenticate command
case MC_AUTH_A: case MC_AUTH_A:
case MC_AUTH_B: case MC_AUTH_B:
szParamLen = sizeof(struct mifare_param_auth); szParamLen = sizeof (mifare_param_auth);
break; break;
// Data command // Data command
case MC_WRITE: case MC_WRITE:
szParamLen = sizeof(struct mifare_param_data); szParamLen = sizeof (mifare_param_data);
break; break;
// Value command // Value command
case MC_DECREMENT: case MC_DECREMENT:
case MC_INCREMENT: case MC_INCREMENT:
case MC_TRANSFER: case MC_TRANSFER:
szParamLen = sizeof(struct mifare_param_value); szParamLen = sizeof (mifare_param_value);
break; break;
// Please fix your code, you never should reach this statement // Please fix your code, you never should reach this statement
default: default:
return false; return false;
break;
} }
// When available, copy the parameter bytes // When available, copy the parameter bytes
if (szParamLen) if (szParamLen)
memcpy(abtCmd + 2, (uint8_t *) pmp, szParamLen); memcpy (abtCmd + 2, (byte_t *) pmp, szParamLen);
// FIXME: Save and restore bEasyFraming bEasyFraming = pnd->bEasyFraming;
// bEasyFraming = nfc_device_get_property_bool (pnd, NP_EASY_FRAMING, &bEasyFraming); if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) {
if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, true) < 0) { nfc_perror (pnd, "nfc_configure");
nfc_perror(pnd, "nfc_device_set_property_bool");
return false; return false;
} }
// Fire the mifare command // Fire the mifare command
int res; if (!nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRx)) {
if ((res = nfc_initiator_transceive_bytes(pnd, abtCmd, 2 + szParamLen, abtRx, sizeof(abtRx), -1)) < 0) { if (pnd->iLastError == EINVRXFRAM) {
if (res == NFC_ERFTRANS) { // "Invalid received frame" AKA EINVRXFRAM, usual means we are
// "Invalid received frame", usual means we are
// authenticated on a sector but the requested MIFARE cmd (read, write) // authenticated on a sector but the requested MIFARE cmd (read, write)
// is not permitted by current acces bytes; // is not permitted by current acces bytes;
// So there is nothing to do here. // So there is nothing to do here.
} else { } else {
nfc_perror(pnd, "nfc_initiator_transceive_bytes"); nfc_perror (pnd, "nfc_initiator_transceive_bytes");
} }
// XXX nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming); nfc_configure (pnd, NDO_EASY_FRAMING, bEasyFraming);
return false; return false;
} }
/* XXX if (!nfc_configure (pnd, NDO_EASY_FRAMING, bEasyFraming)) {
if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming) < 0) { nfc_perror (pnd, "nfc_configure");
nfc_perror (pnd, "nfc_device_set_property_bool");
return false; return false;
} }
*/
// When we have executed a read command, copy the received bytes into the param // When we have executed a read command, copy the received bytes into the param
if (mc == MC_READ) { if (mc == MC_READ) {
if (szRx == 16) {
//Check the length of response data, with PCSC reader, there have 2 bytes for SW value memcpy (pmp->mpd.abtData, abtRx, 16);
if (res == 16 || res == (16 + 2)) {
memcpy(pmp->mpd.abtData, abtRx, 16);
} else { } else {
return false; return false;
} }

139
examples/mifare.h Normal file
View File

@ -0,0 +1,139 @@
/*-
* Public platform independent Near Field Communication (NFC) library examples
*
* Copyright (C) 2009, Roel Verdult
* Copyright (C) 2010, Romuald Conty, Romain Tartière
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Note that this license only applies on the examples, NFC library itself is under LGPL
*
*/
/**
* @file mifaretag.h
* @brief provide samples structs and functions to manipulate MIFARE Classic and Ultralight tags using libnfc
*/
#ifndef _LIBNFC_MIFARE_H_
# define _LIBNFC_MIFARE_H_
# include <nfc/nfc-types.h>
// Compiler directive, set struct alignment to 1 byte_t for compatibility
# pragma pack(1)
typedef enum {
MC_AUTH_A = 0x60,
MC_AUTH_B = 0x61,
MC_READ = 0x30,
MC_WRITE = 0xA0,
MC_TRANSFER = 0xB0,
MC_DECREMENT = 0xC0,
MC_INCREMENT = 0xC1,
MC_STORE = 0xC2
} mifare_cmd;
// MIFARE command params
typedef struct {
byte_t abtKey[6];
byte_t abtUid[4];
} mifare_param_auth;
typedef struct {
byte_t abtData[16];
} mifare_param_data;
typedef struct {
byte_t abtValue[4];
} mifare_param_value;
typedef union {
mifare_param_auth mpa;
mifare_param_data mpd;
mifare_param_value mpv;
} mifare_param;
// Reset struct alignment to default
# pragma pack()
bool nfc_initiator_mifare_cmd (nfc_device_t * pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param * pmp);
// Compiler directive, set struct alignment to 1 byte_t for compatibility
# pragma pack(1)
// MIFARE Classic
typedef struct {
byte_t abtUID[4];
byte_t btBCC;
byte_t btUnknown;
byte_t abtATQA[2];
byte_t abtUnknown[8];
} mifare_classic_block_manufacturer;
typedef struct {
byte_t abtData[16];
} mifare_classic_block_data;
typedef struct {
byte_t abtKeyA[6];
byte_t abtAccessBits[4];
byte_t abtKeyB[6];
} mifare_classic_block_trailer;
typedef union {
mifare_classic_block_manufacturer mbm;
mifare_classic_block_data mbd;
mifare_classic_block_trailer mbt;
} mifare_classic_block;
typedef struct {
mifare_classic_block amb[256];
} mifare_classic_tag;
// MIFARE Ultralight
typedef struct {
byte_t sn0[3];
byte_t btBCC0;
byte_t sn1[4];
byte_t btBCC1;
byte_t internal;
byte_t lock[2];
byte_t otp[4];
} mifareul_block_manufacturer;
typedef struct {
byte_t abtData[16];
} mifareul_block_data;
typedef union {
mifareul_block_manufacturer mbm;
mifareul_block_data mbd;
} mifareul_block;
typedef struct {
mifareul_block amb[4];
} mifareul_tag;
// Reset struct alignment to default
# pragma pack()
#endif // _LIBNFC_MIFARE_H_

View File

@ -1,4 +1,4 @@
.TH nfc-anticol 1 "June 26, 2009" "libnfc" "libnfc's examples" .TH NFC-ANTICOL 1 "June 26, 2009"
.SH NAME .SH NAME
nfc-anticol \- Demonstration of NFC anti-collision command line tool based on libnfc nfc-anticol \- Demonstration of NFC anti-collision command line tool based on libnfc
.SH SYNOPSIS .SH SYNOPSIS
@ -21,17 +21,13 @@ are neither 0 nor 1.
.SH BUGS .SH BUGS
Please report any bugs on the Please report any bugs on the
.B libnfc .B libnfc
issue tracker at: forum at
.br .BR http://www.libnfc.org/community/ "."
.BR https://github.com/nfc-tools/libnfc/issues
.SH LICENCE .SH LICENCE
.B libnfc .B libnfc
is licensed under the GNU Lesser General Public License (LGPL), version 3.
.br
.B libnfc-utils
and and
.B libnfc-examples .B libnfc-examples
are covered by the the BSD 2-Clause license. are covered by the GNU Lesser General Public License (LGPL), version 3.
.SH AUTHORS .SH AUTHORS
Roel Verdult <roel@libnfc.org> Roel Verdult <roel@libnfc.org>
.PP .PP

View File

@ -1,19 +1,12 @@
/*- /*-
* Free/Libre Near Field Communication (NFC) library * Public platform independent Near Field Communication (NFC) library examples
* *
* Libnfc historical contributors: * Copyright (C) 2009, Roel Verdult
* Copyright (C) 2009 Roel Verdult *
* Copyright (C) 2009-2013 Romuald Conty
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice, * 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright * 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
@ -29,12 +22,12 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* Note that this license only applies on the examples, NFC library itself is under LGPL * Note that this license only applies on the examples, NFC library itself is under LGPL
* *
*/ */
/** /**
* @file nfc-anticol.c * @file nfc-anticol.c
* @brief Generates one ISO14443-A anti-collision process "by-hand" * @brief Generates one ISO14443-A anti-collision process "by-hand"
*/ */
@ -52,60 +45,48 @@
#include <nfc/nfc.h> #include <nfc/nfc.h>
#include "utils/nfc-utils.h" #include <nfc/nfc-messages.h>
#include "nfc-utils.h"
#define SAK_FLAG_ATS_SUPPORTED 0x20 #define SAK_FLAG_ATS_SUPPORTED 0x20
#define MAX_FRAME_LEN 264 #define MAX_FRAME_LEN 264
static uint8_t abtRx[MAX_FRAME_LEN]; static byte_t abtRx[MAX_FRAME_LEN];
static int szRxBits; static size_t szRxBits;
static size_t szRx = sizeof(abtRx); static size_t szRx;
static uint8_t abtRawUid[12]; static byte_t abtRawUid[12];
static uint8_t abtAtqa[2]; static byte_t abtAtqa[2];
static uint8_t abtSak; static byte_t abtSak;
static uint8_t abtAts[MAX_FRAME_LEN];
static uint8_t szAts = 0;
static size_t szCL = 1;//Always start with Cascade Level 1 (CL1) static size_t szCL = 1;//Always start with Cascade Level 1 (CL1)
static nfc_device *pnd; static nfc_device_t *pnd;
bool quiet_output = false; bool quiet_output = false;
bool force_rats = false;
bool timed = false;
bool iso_ats_supported = false;
// ISO14443A Anti-Collision Commands // ISO14443A Anti-Collision Commands
uint8_t abtReqa[1] = { 0x26 }; byte_t abtReqa[1] = { 0x26 };
uint8_t abtSelectAll[2] = { 0x93, 0x20 }; byte_t abtSelectAll[2] = { 0x93, 0x20 };
uint8_t abtSelectTag[9] = { 0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; byte_t abtSelectTag[9] = { 0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t abtRats[4] = { 0xe0, 0x50, 0x00, 0x00 }; byte_t abtRats[4] = { 0xe0, 0x50, 0x00, 0x00 };
uint8_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 }; byte_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
#define CASCADE_BIT 0x04 #define CASCADE_BIT 0x04
static bool static bool
transmit_bits(const uint8_t *pbtTx, const size_t szTxBits) transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
{ {
uint32_t cycles = 0;
// Show transmitted command // Show transmitted command
if (!quiet_output) { if (!quiet_output) {
printf("Sent bits: "); printf ("Sent bits: ");
print_hex_bits(pbtTx, szTxBits); print_hex_bits (pbtTx, szTxBits);
} }
// Transmit the bit frame command, we don't use the arbitrary parity feature // Transmit the bit frame command, we don't use the arbitrary parity feature
if (timed) { if (!nfc_initiator_transceive_bits (pnd, pbtTx, szTxBits, NULL, abtRx, &szRxBits, NULL))
if ((szRxBits = nfc_initiator_transceive_bits_timed(pnd, pbtTx, szTxBits, NULL, abtRx, sizeof(abtRx), NULL, &cycles)) < 0) return false;
return false;
if ((!quiet_output) && (szRxBits > 0)) {
printf("Response after %u cycles\n", cycles);
}
} else {
if ((szRxBits = nfc_initiator_transceive_bits(pnd, pbtTx, szTxBits, NULL, abtRx, sizeof(abtRx), NULL)) < 0)
return false;
}
// Show received answer // Show received answer
if (!quiet_output) { if (!quiet_output) {
printf("Received bits: "); printf ("Received bits: ");
print_hex_bits(abtRx, szRxBits); print_hex_bits (abtRx, szRxBits);
} }
// Succesful transfer // Succesful transfer
return true; return true;
@ -113,129 +94,115 @@ transmit_bits(const uint8_t *pbtTx, const size_t szTxBits)
static bool static bool
transmit_bytes(const uint8_t *pbtTx, const size_t szTx) transmit_bytes (const byte_t * pbtTx, const size_t szTx)
{ {
uint32_t cycles = 0;
// Show transmitted command // Show transmitted command
if (!quiet_output) { if (!quiet_output) {
printf("Sent bits: "); printf ("Sent bits: ");
print_hex(pbtTx, szTx); print_hex (pbtTx, szTx);
} }
int res;
// Transmit the command bytes // Transmit the command bytes
if (timed) { if (!nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, &szRx))
if ((res = nfc_initiator_transceive_bytes_timed(pnd, pbtTx, szTx, abtRx, sizeof(abtRx), &cycles)) < 0) return false;
return false;
if ((!quiet_output) && (res > 0)) {
printf("Response after %u cycles\n", cycles);
}
} else {
if ((res = nfc_initiator_transceive_bytes(pnd, pbtTx, szTx, abtRx, sizeof(abtRx), 0)) < 0)
return false;
}
szRx = res;
// Show received answer // Show received answer
if (!quiet_output) { if (!quiet_output) {
printf("Received bits: "); printf ("Received bits: ");
print_hex(abtRx, szRx); print_hex (abtRx, szRx);
} }
// Succesful transfer // Succesful transfer
return true; return true;
} }
static void static void
print_usage(char *argv[]) print_usage (char *argv[])
{ {
printf("Usage: %s [OPTIONS]\n", argv[0]); printf ("Usage: %s [OPTIONS]\n", argv[0]);
printf("Options:\n"); printf ("Options:\n");
printf("\t-h\tHelp. Print this message.\n"); printf ("\t-h\tHelp. Print this message.\n");
printf("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n"); printf ("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
printf("\t-f\tForce RATS.\n");
printf("\t-t\tMeasure response time (in cycles).\n");
} }
int int
main(int argc, char *argv[]) main (int argc, char *argv[])
{ {
int arg; int arg;
// Get commandline options // Get commandline options
for (arg = 1; arg < argc; arg++) { for (arg = 1; arg < argc; arg++) {
if (0 == strcmp(argv[arg], "-h")) { if (0 == strcmp (argv[arg], "-h")) {
print_usage(argv); print_usage (argv);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} else if (0 == strcmp(argv[arg], "-q")) { } else if (0 == strcmp (argv[arg], "-q")) {
quiet_output = true; quiet_output = true;
} else if (0 == strcmp(argv[arg], "-f")) {
force_rats = true;
} else if (0 == strcmp(argv[arg], "-t")) {
timed = true;
} else { } else {
ERR("%s is not supported option.", argv[arg]); ERR ("%s is not supported option.", argv[arg]);
print_usage(argv); print_usage (argv);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
nfc_context *context;
nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
// Try to open the NFC reader // Try to open the NFC reader
pnd = nfc_open(context, NULL); pnd = nfc_connect (NULL);
if (pnd == NULL) { if (!pnd) {
ERR("Error opening NFC reader"); printf ("Error connecting NFC reader\n");
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Initialise NFC device as "initiator" // Initialise NFC device as "initiator"
if (nfc_initiator_init(pnd) < 0) { nfc_initiator_init (pnd);
nfc_perror(pnd, "nfc_initiator_init");
nfc_close(pnd); // Drop the field for a while
nfc_exit(context); if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
exit(EXIT_FAILURE); nfc_perror (pnd, "nfc_configure");
exit (EXIT_FAILURE);
} }
// Configure the CRC // Configure the CRC
if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) { if (!nfc_configure (pnd, NDO_HANDLE_CRC, false)) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror (pnd, "nfc_configure");
nfc_close(pnd); exit (EXIT_FAILURE);
nfc_exit(context); }
exit(EXIT_FAILURE); // Configure parity settings
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
nfc_perror (pnd, "nfc_configure");
exit (EXIT_FAILURE);
} }
// Use raw send/receive methods // Use raw send/receive methods
if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) { if (!nfc_configure (pnd, NDO_EASY_FRAMING, false)) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror (pnd, "nfc_configure");
nfc_close(pnd); exit (EXIT_FAILURE);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
// Disable 14443-4 autoswitching // Disable 14443-4 autoswitching
if (nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, false) < 0) { if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, false)) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror (pnd, "nfc_configure");
nfc_close(pnd); exit (EXIT_FAILURE);
nfc_exit(context); }
exit(EXIT_FAILURE); // Force 14443-A mode
if (!nfc_configure (pnd, NDO_FORCE_ISO14443_A, true)) {
nfc_perror (pnd, "nfc_configure");
exit (EXIT_FAILURE);
} }
printf("NFC reader: %s opened\n\n", nfc_device_get_name(pnd)); // Enable field so more power consuming cards can power themselves up
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
nfc_perror (pnd, "nfc_configure");
exit (EXIT_FAILURE);
}
printf ("Connected to NFC reader: %s\n\n", pnd->acName);
// Send the 7 bits request command specified in ISO 14443A (0x26) // Send the 7 bits request command specified in ISO 14443A (0x26)
if (!transmit_bits(abtReqa, 7)) { if (!transmit_bits (abtReqa, 7)) {
printf("Error: No tag available\n"); printf ("Error: No tag available\n");
nfc_close(pnd); nfc_disconnect (pnd);
nfc_exit(context); return 1;
exit(EXIT_FAILURE);
} }
memcpy(abtAtqa, abtRx, 2); memcpy (abtAtqa, abtRx, 2);
// Anti-collision // Anti-collision
transmit_bytes(abtSelectAll, 2); transmit_bytes (abtSelectAll, 2);
// Check answer // Check answer
if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) { if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) {
@ -243,12 +210,12 @@ main(int argc, char *argv[])
} }
// Save the UID CL1 // Save the UID CL1
memcpy(abtRawUid, abtRx, 4); memcpy (abtRawUid, abtRx, 4);
//Prepare and send CL1 Select-Command //Prepare and send CL1 Select-Command
memcpy(abtSelectTag + 2, abtRx, 5); memcpy (abtSelectTag + 2, abtRx, 5);
iso14443a_crc_append(abtSelectTag, 7); iso14443a_crc_append (abtSelectTag, 7);
transmit_bytes(abtSelectTag, 9); transmit_bytes (abtSelectTag, 9);
abtSak = abtRx[0]; abtSak = abtRx[0];
// Test if we are dealing with a CL2 // Test if we are dealing with a CL2
@ -260,14 +227,14 @@ main(int argc, char *argv[])
} }
} }
if (szCL == 2) { if(szCL == 2) {
// We have to do the anti-collision for cascade level 2 // We have to do the anti-collision for cascade level 2
// Prepare CL2 commands // Prepare CL2 commands
abtSelectAll[0] = 0x95; abtSelectAll[0] = 0x95;
// Anti-collision // Anti-collision
transmit_bytes(abtSelectAll, 2); transmit_bytes (abtSelectAll, 2);
// Check answer // Check answer
if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) { if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) {
@ -275,13 +242,13 @@ main(int argc, char *argv[])
} }
// Save UID CL2 // Save UID CL2
memcpy(abtRawUid + 4, abtRx, 4); memcpy (abtRawUid + 4, abtRx, 4);
// Selection // Selection
abtSelectTag[0] = 0x95; abtSelectTag[0] = 0x95;
memcpy(abtSelectTag + 2, abtRx, 5); memcpy (abtSelectTag + 2, abtRx, 5);
iso14443a_crc_append(abtSelectTag, 7); iso14443a_crc_append (abtSelectTag, 7);
transmit_bytes(abtSelectTag, 9); transmit_bytes (abtSelectTag, 9);
abtSak = abtRx[0]; abtSak = abtRx[0];
// Test if we are dealing with a CL3 // Test if we are dealing with a CL3
@ -293,12 +260,12 @@ main(int argc, char *argv[])
} }
} }
if (szCL == 3) { if ( szCL == 3) {
// We have to do the anti-collision for cascade level 3 // We have to do the anti-collision for cascade level 3
// Prepare and send CL3 AC-Command // Prepare and send CL3 AC-Command
abtSelectAll[0] = 0x97; abtSelectAll[0] = 0x97;
transmit_bytes(abtSelectAll, 2); transmit_bytes (abtSelectAll, 2);
// Check answer // Check answer
if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) { if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) {
@ -306,59 +273,45 @@ main(int argc, char *argv[])
} }
// Save UID CL3 // Save UID CL3
memcpy(abtRawUid + 8, abtRx, 4); memcpy (abtRawUid + 8, abtRx, 4);
// Prepare and send final Select-Command // Prepare and send final Select-Command
abtSelectTag[0] = 0x97; abtSelectTag[0] = 0x97;
memcpy(abtSelectTag + 2, abtRx, 5); memcpy (abtSelectTag + 2, abtRx, 5);
iso14443a_crc_append(abtSelectTag, 7); iso14443a_crc_append (abtSelectTag, 7);
transmit_bytes(abtSelectTag, 9); transmit_bytes (abtSelectTag, 9);
abtSak = abtRx[0]; abtSak = abtRx[0];
} }
} }
// Request ATS, this only applies to tags that support ISO 14443A-4 // Request ATS, this only applies to tags that support ISO 14443A-4
if (abtRx[0] & SAK_FLAG_ATS_SUPPORTED) { if (abtRx[0] & SAK_FLAG_ATS_SUPPORTED) {
iso_ats_supported = true;
}
if ((abtRx[0] & SAK_FLAG_ATS_SUPPORTED) || force_rats) {
iso14443a_crc_append(abtRats, 2); iso14443a_crc_append(abtRats, 2);
if (transmit_bytes(abtRats, 4)) { transmit_bytes (abtRats, 4);
memcpy(abtAts, abtRx, szRx);
szAts = szRx;
}
} }
// Done, halt the tag now // Done, halt the tag now
iso14443a_crc_append(abtHalt, 2); iso14443a_crc_append(abtHalt, 2);
transmit_bytes(abtHalt, 4); transmit_bytes (abtHalt, 4);
printf("\nFound tag with\n UID: "); printf ("\nFound tag with\n UID: ");
switch (szCL) { switch (szCL) {
case 1: case 1:
printf("%02x%02x%02x%02x", abtRawUid[0], abtRawUid[1], abtRawUid[2], abtRawUid[3]); printf ("%02x%02x%02x%02x", abtRawUid[0], abtRawUid[1], abtRawUid[2], abtRawUid[3]);
break; break;
case 2: case 2:
printf("%02x%02x%02x", abtRawUid[1], abtRawUid[2], abtRawUid[3]); printf ("%02x%02x%02x", abtRawUid[1], abtRawUid[2], abtRawUid[3]);
printf("%02x%02x%02x%02x", abtRawUid[4], abtRawUid[5], abtRawUid[6], abtRawUid[7]); printf ("%02x%02x%02x%02x", abtRawUid[4], abtRawUid[5], abtRawUid[6], abtRawUid[7]);
break; break;
case 3: case 3:
printf("%02x%02x%02x", abtRawUid[1], abtRawUid[2], abtRawUid[3]); printf ("%02x%02x%02x", abtRawUid[1], abtRawUid[2], abtRawUid[3]);
printf("%02x%02x%02x", abtRawUid[5], abtRawUid[6], abtRawUid[7]); printf ("%02x%02x%02x", abtRawUid[5], abtRawUid[6], abtRawUid[7]);
printf("%02x%02x%02x%02x", abtRawUid[8], abtRawUid[9], abtRawUid[10], abtRawUid[11]); printf ("%02x%02x%02x%02x", abtRawUid[8], abtRawUid[9], abtRawUid[10], abtRawUid[11]);
break; break;
} }
printf("\n"); printf("\n");
printf("ATQA: %02x%02x\n SAK: %02x\n", abtAtqa[1], abtAtqa[0], abtSak); printf("ATQA: %02x%02x\n SAK: %02x\n", abtAtqa[1], abtAtqa[0], abtSak);
if (szAts > 1) { // if = 1, it's not actual ATS but error code
if (force_rats && ! iso_ats_supported) {
printf(" RATS forced\n");
}
printf(" ATS: ");
print_hex(abtAts, szAts);
}
nfc_close(pnd); nfc_disconnect (pnd);
nfc_exit(context); return 0;
exit(EXIT_SUCCESS);
} }

View File

@ -1,4 +1,4 @@
.TH nfc-dep-initiator 1 "October 8, 2010" "libnfc" "libnfc's examples" .TH NFC-DEP-INITIATOR 1 "October 8, 2010"
.SH NAME .SH NAME
nfc-dep-initiator \- Demonstration tool to send/received data as D.E.P. initiator nfc-dep-initiator \- Demonstration tool to send/received data as D.E.P. initiator
.SH SYNOPSIS .SH SYNOPSIS
@ -7,30 +7,23 @@ nfc-dep-initiator \- Demonstration tool to send/received data as D.E.P. initiato
.B nfc-dep-initiator .B nfc-dep-initiator
is a demonstration tool for putting NFC device in D.E.P. initiator mode. is a demonstration tool for putting NFC device in D.E.P. initiator mode.
This example will attempt to select a passive D.E.P. target and exchange a This example will attempt to select a passive D.E.P. target and exchange a simple "Hello" data with target.
simple "Hello" data with target.
Note: this example is designed to work with a D.E.P. target driven by Note: this example is designed to work with a D.E.P. target driven by \fBnfc-dep-target\fP
\fBnfc-dep-target\fP
.SH BUGS .SH BUGS
Please report any bugs on the Please report any bugs on the
.B libnfc .B libnfc
issue tracker at: forum at
.br .BR http://www.libnfc.org/community/ "."
.BR https://github.com/nfc-tools/libnfc/issues
.SH LICENCE .SH LICENCE
.B libnfc .B libnfc
is licensed under the GNU Lesser General Public License (LGPL), version 3.
.br
.B libnfc-utils
and and
.B libnfc-examples .B libnfc-examples
are covered by the the BSD 2-Clause license. are covered by the GNU Lesser General Public License (LGPL), version 3.
.SH AUTHORS .SH AUTHORS
Roel Verdult <roel@libnfc.org>, Roel Verdult <roel@libnfc.org>
.br Romuald Conty <romuald@libnfc.org>
Romuald Conty <romuald@libnfc.org>.
.PP .PP
This manual page was written by Romuald Conty <romuald@libnfc.org>. This manual page was written by Romuald Conty <romuald@libnfc.org>.
It is licensed under the terms of the GNU GPL (version 2 or later). It is licensed under the terms of the GNU GPL (version 2 or later).

View File

@ -1,19 +1,13 @@
/*- /*-
* Free/Libre Near Field Communication (NFC) library * Public platform independent Near Field Communication (NFC) library examples
* *
* Libnfc historical contributors: * Copyright (C) 2009, Roel Verdult
* Copyright (C) 2009 Roel Verdult * Copyright (C) 2010, Romuald Conty
* Copyright (C) 2009-2013 Romuald Conty *
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice, * 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright * 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
@ -29,7 +23,7 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* Note that this license only applies on the examples, NFC library itself is under LGPL * Note that this license only applies on the examples, NFC library itself is under LGPL
* *
*/ */
@ -46,91 +40,55 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <signal.h>
#include <nfc/nfc.h> #include <nfc/nfc.h>
#include "utils/nfc-utils.h" #include "nfc-utils.h"
#define MAX_FRAME_LEN 264 #define MAX_FRAME_LEN 264
static nfc_device *pnd;
static nfc_context *context;
static void stop_dep_communication(int sig)
{
(void) sig;
if (pnd != NULL) {
nfc_abort_command(pnd);
} else {
nfc_exit(context);
exit(EXIT_FAILURE);
}
}
int int
main(int argc, const char *argv[]) main (int argc, const char *argv[])
{ {
nfc_target nt; nfc_device_t *pnd;
uint8_t abtRx[MAX_FRAME_LEN]; nfc_target_t nt;
uint8_t abtTx[] = "Hello World!"; byte_t abtRx[MAX_FRAME_LEN];
size_t szRx;
byte_t abtTx[] = "Hello World!";
if (argc > 1) { if (argc > 1) {
printf("Usage: %s\n", argv[0]); printf ("Usage: %s\n", argv[0]);
exit(EXIT_FAILURE); return EXIT_FAILURE;
} }
nfc_init(&context); pnd = nfc_connect (NULL);
if (context == NULL) { if (!pnd) {
ERR("Unable to init libnfc (malloc)"); printf("Unable to connect to NFC device.\n");
exit(EXIT_FAILURE); return EXIT_FAILURE;
} }
printf ("Connected to NFC device: %s\n", pnd->acName);
pnd = nfc_open(context, NULL); if (!nfc_initiator_init (pnd)) {
if (pnd == NULL) {
ERR("Unable to open NFC device.");
nfc_exit(context);
exit(EXIT_FAILURE);
}
printf("NFC device: %s\n opened", nfc_device_get_name(pnd));
signal(SIGINT, stop_dep_communication);
if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init"); nfc_perror(pnd, "nfc_initiator_init");
nfc_close(pnd); return EXIT_FAILURE;
nfc_exit(context);
exit(EXIT_FAILURE);
} }
if (nfc_initiator_select_dep_target(pnd, NDM_PASSIVE, NBR_212, NULL, &nt, 1000) < 0) { if(!nfc_initiator_select_dep_target (pnd, NDM_PASSIVE, NBR_212, NULL, &nt)) {
nfc_perror(pnd, "nfc_initiator_select_dep_target"); nfc_perror(pnd, "nfc_initiator_select_dep_target");
nfc_close(pnd); return EXIT_FAILURE;
nfc_exit(context);
exit(EXIT_FAILURE);
} }
print_nfc_target(&nt, false); print_nfc_target (nt, false);
printf("Sending: %s\n", abtTx); printf ("Sending: %s\n", abtTx);
int res; if (!nfc_initiator_transceive_bytes (pnd, abtTx, sizeof(abtTx), abtRx, &szRx)) {
if ((res = nfc_initiator_transceive_bytes(pnd, abtTx, sizeof(abtTx), abtRx, sizeof(abtRx), 0)) < 0) {
nfc_perror(pnd, "nfc_initiator_transceive_bytes"); nfc_perror(pnd, "nfc_initiator_transceive_bytes");
nfc_close(pnd); return EXIT_FAILURE;
nfc_exit(context);
exit(EXIT_FAILURE);
} }
abtRx[res] = 0; abtRx[szRx] = 0;
printf("Received: %s\n", abtRx); printf ("Received: %s\n", abtRx);
if (nfc_initiator_deselect_target(pnd) < 0) { nfc_initiator_deselect_target (pnd);
nfc_perror(pnd, "nfc_initiator_deselect_target"); nfc_disconnect (pnd);
nfc_close(pnd); return EXIT_SUCCESS;
nfc_exit(context);
exit(EXIT_FAILURE);
}
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_SUCCESS);
} }

View File

@ -1,4 +1,4 @@
.TH nfc-dep-target 1 "October 8, 2010" "libnfc" "libnfc's examples" .TH NFC-DEP-INITIATOR 1 "October 8, 2010"
.SH NAME .SH NAME
nfc-dep-target \- Demonstration tool to send/received data as D.E.P. target nfc-dep-target \- Demonstration tool to send/received data as D.E.P. target
.SH SYNOPSIS .SH SYNOPSIS
@ -7,30 +7,23 @@ nfc-dep-target \- Demonstration tool to send/received data as D.E.P. target
.B nfc-dep-target .B nfc-dep-target
is a demonstration tool for putting NFC device in D.E.P. target mode. is a demonstration tool for putting NFC device in D.E.P. target mode.
This example will listen for a D.E.P. initiator and exchange a simple "Hello" This example will listen for a D.E.P. initiator and exchange a simple "Hello" data with initiator.
data with initiator.
Note: this example is designed to work with a D.E.P. initiator driven by Note: this example is designed to work with a D.E.P. initiator driven by \fBnfc-dep-initiator\fP.
\fBnfc-dep-initiator\fP.
.SH BUGS .SH BUGS
Please report any bugs on the Please report any bugs on the
.B libnfc .B libnfc
issue tracker at: forum at
.br .BR http://www.libnfc.org/community/ "."
.BR https://github.com/nfc-tools/libnfc/issues
.SH LICENCE .SH LICENCE
.B libnfc .B libnfc
is licensed under the GNU Lesser General Public License (LGPL), version 3.
.br
.B libnfc-utils
and and
.B libnfc-examples .B libnfc-examples
are covered by the the BSD 2-Clause license. are covered by the GNU Lesser General Public License (LGPL), version 3.
.SH AUTHORS .SH AUTHORS
Roel Verdult <roel@libnfc.org>, Roel Verdult <roel@libnfc.org>
.br Romuald Conty <romuald@libnfc.org>
Romuald Conty <romuald@libnfc.org>.
.PP .PP
This manual page was written by Romuald Conty <romuald@libnfc.org>. This manual page was written by Romuald Conty <romuald@libnfc.org>.
It is licensed under the terms of the GNU GPL (version 2 or later). It is licensed under the terms of the GNU GPL (version 2 or later).

View File

@ -1,19 +1,13 @@
/*- /*-
* Free/Libre Near Field Communication (NFC) library * Public platform independent Near Field Communication (NFC) library examples
* *
* Libnfc historical contributors: * Copyright (C) 2009, Roel Verdult
* Copyright (C) 2009 Roel Verdult * Copyright (C) 2010, Romuald Conty
* Copyright (C) 2009-2013 Romuald Conty *
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice, * 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright * 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
@ -29,7 +23,7 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* Note that this license only applies on the examples, NFC library itself is under LGPL * Note that this license only applies on the examples, NFC library itself is under LGPL
* *
*/ */
@ -45,123 +39,86 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h>
#include <nfc/nfc.h> #include <nfc/nfc.h>
#include "utils/nfc-utils.h" #include "nfc-utils.h"
#define MAX_FRAME_LEN 264 #define MAX_FRAME_LEN 264
static nfc_device *pnd;
static nfc_context *context;
static void stop_dep_communication(int sig)
{
(void) sig;
if (pnd != NULL) {
nfc_abort_command(pnd);
} else {
nfc_exit(context);
exit(EXIT_FAILURE);
}
}
int int
main(int argc, const char *argv[]) main (int argc, const char *argv[])
{ {
uint8_t abtRx[MAX_FRAME_LEN]; byte_t abtRx[MAX_FRAME_LEN];
int szRx; size_t szRx;
uint8_t abtTx[] = "Hello Mars!"; size_t szDeviceFound;
byte_t abtTx[] = "Hello Mars!";
if (argc > 1) { nfc_device_t *pnd;
printf("Usage: %s\n", argv[0]); #define MAX_DEVICE_COUNT 2
exit(EXIT_FAILURE); nfc_device_desc_t pnddDevices[MAX_DEVICE_COUNT];
} nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szDeviceFound);
nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
#define MAX_DEVICE_COUNT 2
nfc_connstring connstrings[MAX_DEVICE_COUNT];
size_t szDeviceFound = nfc_list_devices(context, connstrings, MAX_DEVICE_COUNT);
// Little hack to allow using nfc-dep-initiator & nfc-dep-target from // Little hack to allow using nfc-dep-initiator & nfc-dep-target from
// the same machine: if there is more than one readers opened // the same machine: if there is more than one readers connected
// nfc-dep-target will open the second reader // nfc-dep-target will connect to the second reader
// (we hope they're always detected in the same order) // (we hope they're always detected in the same order)
if (szDeviceFound == 1) { if (szDeviceFound == 1) {
pnd = nfc_open(context, connstrings[0]); pnd = nfc_connect (&(pnddDevices[0]));
} else if (szDeviceFound > 1) { } else if (szDeviceFound > 1) {
pnd = nfc_open(context, connstrings[1]); pnd = nfc_connect (&(pnddDevices[1]));
} else { } else {
printf("No device found.\n"); printf("No device found.");
nfc_exit(context); return EXIT_FAILURE;
exit(EXIT_FAILURE);
} }
nfc_target nt = { if (argc > 1) {
.nm = { printf ("Usage: %s\n", argv[0]);
.nmt = NMT_DEP, return EXIT_FAILURE;
.nbr = NBR_UNDEFINED }
},
.nti = { nfc_target_t nt = {
.ndi = { .nm.nmt = NMT_DEP,
.abtNFCID3 = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0x00, 0x00 }, .nm.nbr = NBR_UNDEFINED, // Will be updated by nfc_target_init
.szGB = 4, .nti.ndi.abtNFCID3 = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0x00, 0x00 },
.abtGB = { 0x12, 0x34, 0x56, 0x78 }, .nti.ndi.szGB = 4,
.ndm = NDM_UNDEFINED, .nti.ndi.abtGB = { 0x12, 0x34, 0x56, 0x78 },
/* These bytes are not used by nfc_target_init: the chip will provide them automatically to the initiator */ /* These bytes are not used by nfc_target_init: the chip will provide them automatically to the initiator */
.btDID = 0x00, .nti.ndi.btDID = 0x00,
.btBS = 0x00, .nti.ndi.btBS = 0x00,
.btBR = 0x00, .nti.ndi.btBR = 0x00,
.btTO = 0x00, .nti.ndi.btTO = 0x00,
.btPP = 0x01, .nti.ndi.btPP = 0x01,
},
},
}; };
if (pnd == NULL) { if (!pnd) {
printf("Unable to open NFC device.\n"); printf("Unable to connect to NFC device.\n");
nfc_exit(context); return EXIT_FAILURE;
exit(EXIT_FAILURE);
} }
printf("NFC device: %s opened\n", nfc_device_get_name(pnd)); printf ("Connected to NFC device: %s\n", pnd->acName);
signal(SIGINT, stop_dep_communication); printf ("NFC device will now act as: ");
print_nfc_target (nt, false);
printf("NFC device will now act as: "); printf ("Waiting for initiator request...\n");
print_nfc_target(&nt, false); if(!nfc_target_init (pnd, &nt, abtRx, &szRx)) {
printf("Waiting for initiator request...\n");
if ((szRx = nfc_target_init(pnd, &nt, abtRx, sizeof(abtRx), 0)) < 0) {
nfc_perror(pnd, "nfc_target_init"); nfc_perror(pnd, "nfc_target_init");
nfc_close(pnd); return EXIT_FAILURE;
nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("Initiator request received. Waiting for data...\n"); printf("Initiator request received. Waiting for data...\n");
if ((szRx = nfc_target_receive_bytes(pnd, abtRx, sizeof(abtRx), 0)) < 0) { if (!nfc_target_receive_bytes (pnd, abtRx, &szRx)) {
nfc_perror(pnd, "nfc_target_receive_bytes"); nfc_perror(pnd, "nfc_target_receive_bytes");
nfc_close(pnd); return EXIT_FAILURE;
nfc_exit(context);
exit(EXIT_FAILURE);
} }
abtRx[(size_t) szRx] = '\0'; abtRx[szRx] = '\0';
printf("Received: %s\n", abtRx); printf ("Received: %s\n", abtRx);
printf("Sending: %s\n", abtTx); printf ("Sending: %s\n", abtTx);
if (nfc_target_send_bytes(pnd, abtTx, sizeof(abtTx), 0) < 0) { if (!nfc_target_send_bytes (pnd, abtTx, sizeof(abtTx))) {
nfc_perror(pnd, "nfc_target_send_bytes"); nfc_perror(pnd, "nfc_target_send_bytes");
nfc_close(pnd); return EXIT_FAILURE;
nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("Data sent.\n"); printf("Data sent.\n");
nfc_close(pnd); nfc_disconnect (pnd);
nfc_exit(context); return EXIT_SUCCESS;
exit(EXIT_SUCCESS);
} }

View File

@ -1,52 +0,0 @@
.Dd September 19, 2012
.Dt NFC-EMULATE-FORUM-TAG2 1 URM
.Sh NAME
.Nm nfc-emulate-forum-tag2
.Nd NFC Forum tag type 2 emulation command line demonstration tool
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION
.Nm
is a demonstration tool that emulates a NFC-Forum Tag Type 2 with NDEF content.
.Pp
Some devices compliant with NFC-Forum Tag Type 2 can be used with this example,
in read mode only.
.Sh IMPORTANT
This example has been developed using PN533 USB hardware as target and Google
Nexus S phone as initiator.
.Pp
This is know to NOT work with Nokia 6212 Classic and could fail with several
NFC Forum compliant devices due to the following reasons:
.Pp
- The emulated target has only a 4-byte UID while most devices assume a
Tag Type 2 has always a 7-byte UID (as a real Mifare Ultralight tag);
.Pp
- The chip is emulating an ISO/IEC 14443-3 tag, without any hardware helper.
If the initiator have too strict timeouts for software-based emulation
(which is usually the case), this example will fail.
This is not a bug and we can't do anything using this hardware (PN531/PN533).
.Pp
ACR122 devices (like touchatag, etc.) can be used by this example, but if
something goes wrong, you will have to unplug/replug your device.
This is not a
.Em libnfc's
bug, this problem is due to ACR122's internal MCU in front of NFC chip (PN532).
.Sh BUGS
Please report any bugs on the
.Em libnfc
issue tracker at:
.Em https://github.com/nfc-tools/libnfc/issues
.Sh LICENCE
.Em libnfc
is licensed under the GNU Lesser General Public License (LGPL), version 3.
.Em libnfc-utils
and
.Em libnfc-examples
are covered by the BSD 2-Clause license.
.Sh AUTHORS
.An Roel Verdult Aq roel@libnfc.org
.An Romain Tartière Aq romain@libnfc.org
.An Romuald Conty Aq romuald@libnfc.org
.Pp
This manual page was written by Romuald Conty.
It is licensed under the terms of the GNU GPL (version 2 or later).

View File

@ -1,223 +0,0 @@
/*-
* Free/Libre Near Field Communication (NFC) library
*
* Libnfc historical contributors:
* Copyright (C) 2009 Roel Verdult
* Copyright (C) 2009-2013 Romuald Conty
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Note that this license only applies on the examples, NFC library itself is under LGPL
*
*/
/**
* @file nfc-emulate-forum-tag2.c
* @brief Emulates a NFC-Forum Tag Type 2 with a NDEF message
* This example allow to emulate an NFC-Forum Tag Type 2 that contains
* a read-only NDEF message.
*
* This example has been developed using PN533 USB hardware as target and
* Google Nexus S phone as initiator.
*
* This is know to NOT work with Nokia 6212 Classic and could fail with
* several NFC Forum compliant devices due to the following reasons:
* - The emulated target has only a 4-byte UID while most devices assume a Tag
* Type 2 has always a 7-byte UID (as a real Mifare Ultralight tag);
* - The chip is emulating an ISO/IEC 14443-3 tag, without any hardware helper.
* If the initiator has too strict timeouts for software-based emulation
* (which is usually the case), this example will fail. This is not a bug
* and we can't do anything using this hardware (PN531/PN533).
*/
/*
* This implementation was written based on information provided by the
* following documents:
*
* NFC Forum Type 2 Tag Operation
* Technical Specification
* NFCForum-TS-Type-2-Tag_1.0 - 2007-07-09
*
* ISO/IEC 14443-3
* First edition - 2001-02-01
* Identification cards Contactless integrated circuit(s) cards Proximity cards
* Part 3: Initialization and anticollision
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif // HAVE_CONFIG_H
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <nfc/nfc.h>
#include <nfc/nfc-emulation.h>
#include "utils/nfc-utils.h"
static nfc_device *pnd;
static nfc_context *context;
static void
stop_emulation(int sig)
{
(void)sig;
if (pnd != NULL) {
nfc_abort_command(pnd);
} else {
nfc_exit(context);
exit(EXIT_FAILURE);
}
}
static uint8_t __nfcforum_tag2_memory_area[] = {
0x00, 0x00, 0x00, 0x00, // Block 0
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, // Block 2 (Static lock bytes: CC area and data area are read-only locked)
0xE1, 0x10, 0x06, 0x0F, // Block 3 (CC - NFC-Forum Tag Type 2 version 1.0, Data area (from block 4 to the end) is 48 bytes, Read-only mode)
0x03, 33, 0xd1, 0x02, // Block 4 (NDEF)
0x1c, 0x53, 0x70, 0x91,
0x01, 0x09, 0x54, 0x02,
0x65, 0x6e, 0x4c, 0x69,
0x62, 0x6e, 0x66, 0x63,
0x51, 0x01, 0x0b, 0x55,
0x03, 0x6c, 0x69, 0x62,
0x6e, 0x66, 0x63, 0x2e,
0x6f, 0x72, 0x67, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
#define READ 0x30
#define WRITE 0xA2
#define SECTOR_SELECT 0xC2
#define HALT 0x50
static int
nfcforum_tag2_io(struct nfc_emulator *emulator, const uint8_t *data_in, const size_t data_in_len, uint8_t *data_out, const size_t data_out_len)
{
int res = 0;
uint8_t *nfcforum_tag2_memory_area = (uint8_t *)(emulator->user_data);
printf(" In: ");
print_hex(data_in, data_in_len);
switch (data_in[0]) {
case READ:
if (data_out_len >= 16) {
memcpy(data_out, nfcforum_tag2_memory_area + (data_in[1] * 4), 16);
res = 16;
} else {
res = -ENOSPC;
}
break;
case HALT:
printf("HALT sent\n");
res = -ECONNABORTED;
break;
default:
printf("Unknown command: 0x%02x\n", data_in[0]);
res = -ENOTSUP;
}
if (res < 0) {
ERR("%s (%d)", strerror(-res), -res);
} else {
printf(" Out: ");
print_hex(data_out, res);
}
return res;
}
int
main(int argc, char *argv[])
{
(void)argc;
(void)argv;
nfc_target nt = {
.nm = {
.nmt = NMT_ISO14443A,
.nbr = NBR_UNDEFINED, // Will be updated by nfc_target_init()
},
.nti = {
.nai = {
.abtAtqa = { 0x00, 0x04 },
.abtUid = { 0x08, 0x00, 0xb0, 0x0b },
.szUidLen = 4,
.btSak = 0x00,
.szAtsLen = 0,
},
}
};
struct nfc_emulation_state_machine state_machine = {
.io = nfcforum_tag2_io
};
struct nfc_emulator emulator = {
.target = &nt,
.state_machine = &state_machine,
.user_data = __nfcforum_tag2_memory_area,
};
signal(SIGINT, stop_emulation);
nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
pnd = nfc_open(context, NULL);
if (pnd == NULL) {
ERR("Unable to open NFC device");
nfc_exit(context);
exit(EXIT_FAILURE);
}
printf("NFC device: %s opened\n", nfc_device_get_name(pnd));
printf("Emulating NDEF tag now, please touch it with a second NFC device\n");
if (nfc_emulate_target(pnd, &emulator, 0) < 0) {
nfc_perror(pnd, argv[0]);
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
}
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_SUCCESS);
}

View File

@ -0,0 +1,40 @@
.TH NFC-EMULATE-FORUM-TAG4 1 "October 8, 2010"
.SH NAME
nfc-emulate-forum-tag4 \- NFC Forum tag type 4 emulation command line demonstration tool
.SH SYNOPSIS
.B nfc-emulate-forum-tag4
.SH DESCRIPTION
.B nfc-emulate-forum-tag4
is a demonstration tool that emulates a NFC Forum tag type 4 with NDEF content.
Currently, this tool only works with a Nokia 6212 Classic phone as initiator
and a PN532-equipped NFC device as target.
This example uses the hardware capability of PN532 to handle ISO/IEC 14443-4
low-level frames like RATS/ATS, WTX, etc.
At the moment, only the Nokia 6212 Classic can be used with this example
because it's based on a pre-established communication plan and the tool sends
blindly the expected replies to the initiator without having interpreted the queries.
.SH IMPORTANT
ACR122 devices (like touchatag, etc.) can be used by this example, but if
something goes wrong, you will have to unplug/replug your device.
This is not a
.B libnfc's
bug, this problem is due to ACR122's internal MCU in front of NFC chip (PN532).
.SH BUGS
Please report any bugs on the
.B libnfc
forum at
.BR http://www.libnfc.org/community/ "."
.SH LICENCE
.B libnfc
and
.B libnfc-examples
are covered by the GNU Lesser General Public License (LGPL), version 3.
.SH AUTHORS
Roel Verdult <roel@libnfc.org>
.PP
This manual page was written by Romuald Conty <romuald@libnfc.org>.
It is licensed under the terms of the GNU GPL (version 2 or later).

View File

@ -0,0 +1,185 @@
/*-
* Public platform independent Near Field Communication (NFC) library examples
*
* Copyright (C) 2010, Roel Verdult, Romuald Conty
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Note that this license only applies on the examples, NFC library itself is under LGPL
*
*/
/**
* @file nfc-emulate-forum-tag4.c
* @brief Emulates a NFC Forum Tag Type 4 with a NDEF message
*/
// Notes & differences with nfc-emulate-tag:
// - This example only works with PN532 because it relies on
// its internal handling of ISO14443-4 specificities.
// - Thanks to this internal handling & injection of WTX frames,
// this example works on readers very strict on timing
// - This example expects a hardcoded list of commands and
// more precisely the commands sent by a Nokia NFC when
// discovering a NFC-Forum tag type4:
// * Anticoll & RATS
// * App Select by name "e103e103e103"
// * App Select by name "e103e103e103"
// * App Select by name "D2760000850100"
// * Select CC
// * ReadBinary CC
// * Select NDEF
// * Read first 2 NDEF bytes
// * Read remaining of NDEF file
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif // HAVE_CONFIG_H
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <nfc/nfc.h>
#include <nfc/nfc-messages.h>
#include "nfc-utils.h"
#define MAX_FRAME_LEN 264
static byte_t abtRx[MAX_FRAME_LEN];
static size_t szRx;
static nfc_device_t *pnd;
static bool quiet_output = false;
#define SYMBOL_PARAM_fISO14443_4_PICC 0x20
bool send_bytes (const byte_t * pbtTx, const size_t szTx)
{
// Show transmitted command
if (!quiet_output) {
printf ("Sent data: ");
print_hex (pbtTx, szTx);
}
// Transmit the command bytes
if (!nfc_target_send_bytes(pnd, pbtTx, szTx)) {
nfc_perror (pnd, "nfc_target_send_bytes");
exit(EXIT_FAILURE);
}
// Succesful transfer
return true;
}
bool receive_bytes (void)
{
if (!nfc_target_receive_bytes(pnd,abtRx,&szRx)) {
nfc_perror (pnd, "nfc_target_receive_bytes");
exit(EXIT_FAILURE);
}
// Show received answer
if (!quiet_output) {
printf ("Received data: ");
print_hex (abtRx, szRx);
}
// Succesful transfer
return true;
}
int
main (int argc, char *argv[])
{
// Try to open the NFC reader
pnd = nfc_connect (NULL);
if (pnd == NULL) {
ERR("Unable to connect to NFC device");
return EXIT_FAILURE;
}
printf ("Connected to NFC device: %s\n", pnd->acName);
printf ("Emulating NDEF tag now, please touch it with a second NFC device\n");
nfc_target_t nt = {
.nm.nmt = NMT_ISO14443A,
.nm.nbr = NBR_UNDEFINED, // Will be updated by nfc_target_init()
.nti.nai.abtAtqa = { 0x00, 0x04 },
.nti.nai.abtUid = { 0x08, 0x00, 0xb0, 0x0b },
.nti.nai.btSak = 0x20,
.nti.nai.szUidLen = 4,
.nti.nai.szAtsLen = 0,
};
if (!nfc_target_init (pnd, &nt, abtRx, &szRx)) {
nfc_perror (pnd, "nfc_target_init");
ERR("Could not come out of auto-emulation, no command was received");
return EXIT_FAILURE;
}
if (!quiet_output) {
printf ("Received data: ");
print_hex (abtRx, szRx);
}
//Receiving data: e0 40
//= RATS, FSD=48
//Actually PN532 already sent back the ATS so nothing to send now
receive_bytes();
//Receiving data: 00 a4 04 00 06 e1 03 e1 03 e1 03
//= App Select by name "e103e103e103"
send_bytes((const byte_t*)"\x6a\x87",2);
receive_bytes();
//Receiving data: 00 a4 04 00 06 e1 03 e1 03 e1 03
//= App Select by name "e103e103e103"
send_bytes((const byte_t*)"\x6a\x87",2);
receive_bytes();
//Receiving data: 00 a4 04 00 07 d2 76 00 00 85 01 00
//= App Select by name "D2760000850100"
send_bytes((const byte_t*)"\x90\x00",2);
receive_bytes();
//Receiving data: 00 a4 00 00 02 e1 03
//= Select CC
send_bytes((const byte_t*)"\x90\x00",2);
receive_bytes();
//Receiving data: 00 b0 00 00 0f
//= ReadBinary CC
//We send CC + OK
send_bytes((const byte_t*)"\x00\x0f\x10\x00\x3b\x00\x34\x04\x06\xe1\x04\x0e\xe0\x00\x00\x90\x00",17);
receive_bytes();
//Receiving data: 00 a4 00 00 02 e1 04
//= Select NDEF
send_bytes((const byte_t*)"\x90\x00",2);
receive_bytes();
//Receiving data: 00 b0 00 00 02
//= Read first 2 NDEF bytes
//Sent NDEF Length=0x21
send_bytes((const byte_t*)"\x00\x21\x90\x00",4);
receive_bytes();
//Receiving data: 00 b0 00 02 21
//= Read remaining of NDEF file
send_bytes((const byte_t*)"\xd1\x02\x1c\x53\x70\x91\x01\x09\x54\x02\x65\x6e\x4c\x69\x62\x6e\x66\x63\x51\x01\x0b\x55\x03\x6c\x69\x62\x6e\x66\x63\x2e\x6f\x72\x67\x90\x00",35);
nfc_disconnect(pnd);
exit (EXIT_SUCCESS);
}

View File

@ -1,4 +1,4 @@
.TH nfc-emulate-tag 1 "October 8, 2010" "libnfc" "libnfc's examples" .TH NFC-EMULATE-TAG 1 "October 8, 2010"
.SH NAME .SH NAME
nfc-emulate-tag \- Simple tag emulation command line demonstration tool nfc-emulate-tag \- Simple tag emulation command line demonstration tool
.SH SYNOPSIS .SH SYNOPSIS
@ -37,17 +37,13 @@ bug, this problem is due to ACR122's internal MCU in front of NFC chip (PN532).
.SH BUGS .SH BUGS
Please report any bugs on the Please report any bugs on the
.B libnfc .B libnfc
issue tracker at: forum at
.br .BR http://www.libnfc.org/community/ "."
.BR https://github.com/nfc-tools/libnfc/issues
.SH LICENCE .SH LICENCE
.B libnfc .B libnfc
is licensed under the GNU Lesser General Public License (LGPL), version 3.
.br
.B libnfc-utils
and and
.B libnfc-examples .B libnfc-examples
are covered by the the BSD 2-Clause license. are covered by the GNU Lesser General Public License (LGPL), version 3.
.SH AUTHORS .SH AUTHORS
Romuald Conty <romuald@libnfc.org> Romuald Conty <romuald@libnfc.org>
.PP .PP

View File

@ -1,19 +1,12 @@
/*- /*-
* Free/Libre Near Field Communication (NFC) library * Public platform independent Near Field Communication (NFC) library examples
* *
* Libnfc historical contributors: * Copyright (C) 2010, Romuald Conty
* Copyright (C) 2009 Roel Verdult *
* Copyright (C) 2009-2013 Romuald Conty
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice, * 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright * 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
@ -29,7 +22,7 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* Note that this license only applies on the examples, NFC library itself is under LGPL * Note that this license only applies on the examples, NFC library itself is under LGPL
* *
*/ */
@ -56,56 +49,40 @@
#include <nfc/nfc.h> #include <nfc/nfc.h>
#include "utils/nfc-utils.h" #include <nfc/nfc-messages.h>
#include "nfc-utils.h"
#define MAX_FRAME_LEN (264) #define MAX_FRAME_LEN 264
#define SAK_ISO14443_4_COMPLIANT 0x20
static uint8_t abtRx[MAX_FRAME_LEN]; static byte_t abtRx[MAX_FRAME_LEN];
static int szRx; static size_t szRx;
static nfc_context *context; static nfc_device_t *pnd;
static nfc_device *pnd;
static bool quiet_output = false; static bool quiet_output = false;
static bool init_mfc_auth = false; static bool init_mfc_auth = false;
static void void
intr_hdlr(int sig) intr_hdlr (void)
{ {
(void) sig; printf ("\nQuitting...\n");
printf("\nQuitting...\n");
if (pnd != NULL) { if (pnd != NULL) {
nfc_abort_command(pnd); nfc_disconnect(pnd);
} }
nfc_close(pnd); exit (EXIT_FAILURE);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
static bool bool
target_io(nfc_target *pnt, const uint8_t *pbtInput, const size_t szInput, uint8_t *pbtOutput, size_t *pszOutput) target_io( nfc_target_t * pnt, const byte_t * pbtInput, const size_t szInput, byte_t * pbtOutput, size_t *pszOutput )
{ {
bool loop = true; bool loop = true;
*pszOutput = 0; *pszOutput = 0;
// Show transmitted command // Show transmitted command
if (!quiet_output) { if (!quiet_output) {
printf(" In: "); printf (" In: ");
print_hex(pbtInput, szInput); print_hex (pbtInput, szInput);
} }
if (szInput) { if(szInput) {
switch (pbtInput[0]) { switch(pbtInput[0]) {
case 0x30: // Mifare read
// block address is in pbtInput[1]
*pszOutput = 15;
strcpy((char *)pbtOutput, "You read block ");
pbtOutput[15] = pbtInput[1];
break;
case 0x50: // HLTA (ISO14443-3)
if (!quiet_output) {
printf("Initiator HLTA me. Bye!\n");
}
loop = false;
break;
case 0x60: // Mifare authA case 0x60: // Mifare authA
case 0x61: // Mifare authB case 0x61: // Mifare authB
// Let's give back a very random nonce... // Let's give back a very random nonce...
@ -115,17 +92,17 @@ target_io(nfc_target *pnt, const uint8_t *pbtInput, const size_t szInput, uint8_
// Next commands will be without CRC // Next commands will be without CRC
init_mfc_auth = true; init_mfc_auth = true;
break; break;
case 0xe0: // RATS (ISO14443-4) case 0xe0: // RATS
// Send ATS // Send ATS
*pszOutput = pnt->nti.nai.szAtsLen + 1; *pszOutput = pnt->nti.nai.szAtsLen + 1;
pbtOutput[0] = pnt->nti.nai.szAtsLen + 1; // ISO14443-4 says that ATS contains ATS_Length as first byte pbtOutput[0] = pnt->nti.nai.szAtsLen + 1; // ISO14443-4 says that ATS contains ATS_Lenght as first byte
if (pnt->nti.nai.szAtsLen) { if(pnt->nti.nai.szAtsLen) {
memcpy(pbtOutput + 1, pnt->nti.nai.abtAts, pnt->nti.nai.szAtsLen); memcpy(pbtOutput+1, pnt->nti.nai.abtAts, pnt->nti.nai.szAtsLen);
} }
break; break;
case 0xc2: // S-block DESELECT case 0xc2: // S-block DESELECT
if (!quiet_output) { if (!quiet_output) {
printf("Initiator DESELECT me. Bye!\n"); printf("Target released me. Bye!\n");
} }
loop = false; loop = false;
break; break;
@ -138,44 +115,39 @@ target_io(nfc_target *pnt, const uint8_t *pbtInput, const size_t szInput, uint8_
} }
// Show transmitted command // Show transmitted command
if ((!quiet_output) && *pszOutput) { if ((!quiet_output) && *pszOutput) {
printf(" Out: "); printf (" Out: ");
print_hex(pbtOutput, *pszOutput); print_hex (pbtOutput, *pszOutput);
} }
return loop; return loop;
} }
static bool bool
nfc_target_emulate_tag(nfc_device *dev, nfc_target *pnt) nfc_target_emulate_tag(nfc_device_t* pnd, nfc_target_t * pnt)
{ {
size_t szTx; size_t szTx;
uint8_t abtTx[MAX_FRAME_LEN]; byte_t abtTx[MAX_FRAME_LEN];
bool loop = true; bool loop = true;
if ((szRx = nfc_target_init(dev, pnt, abtRx, sizeof(abtRx), 0)) < 0) { if (!nfc_target_init (pnd, pnt, abtRx, &szRx)) {
nfc_perror(dev, "nfc_target_init"); nfc_perror (pnd, "nfc_target_init");
return false; return false;
} }
while (loop) { while ( loop ) {
loop = target_io(pnt, abtRx, (size_t) szRx, abtTx, &szTx); loop = target_io( pnt, abtRx, szRx, abtTx, &szTx );
if (szTx) { if (szTx) {
if (nfc_target_send_bytes(dev, abtTx, szTx, 0) < 0) { if (!nfc_target_send_bytes(pnd, abtTx, szTx)) {
nfc_perror(dev, "nfc_target_send_bytes"); nfc_perror (pnd, "nfc_target_send_bytes");
return false; return false;
} }
} }
if (loop) { if ( loop ) {
if (init_mfc_auth) { if ( init_mfc_auth ) {
if (nfc_device_set_property_bool(dev, NP_HANDLE_CRC, false) < 0) { nfc_configure (pnd, NDO_HANDLE_CRC, false);
nfc_perror(pnd, "nfc_target_emulate_tag");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
}
init_mfc_auth = false; init_mfc_auth = false;
} }
if ((szRx = nfc_target_receive_bytes(dev, abtRx, sizeof(abtRx), 0)) < 0) { if (!nfc_target_receive_bytes(pnd, abtRx, &szRx)) {
nfc_perror(dev, "nfc_target_receive_bytes"); nfc_perror (pnd, "nfc_target_receive_bytes");
return false; return false;
} }
} }
@ -184,119 +156,75 @@ nfc_target_emulate_tag(nfc_device *dev, nfc_target *pnt)
} }
int int
main(int argc, char *argv[]) main (int argc, char *argv[])
{ {
(void) argc;
const char *acLibnfcVersion; const char *acLibnfcVersion;
#ifdef WIN32 #ifdef WIN32
signal(SIGINT, (void (__cdecl *)(int)) intr_hdlr); signal (SIGINT, (void (__cdecl *) (int)) intr_hdlr);
#else #else
signal(SIGINT, intr_hdlr); signal (SIGINT, (void (*)()) intr_hdlr);
#endif #endif
nfc_init(&context); // Try to open the NFC reader
if (context == NULL) { pnd = nfc_connect (NULL);
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
// Display libnfc version // Display libnfc version
acLibnfcVersion = nfc_version(); acLibnfcVersion = nfc_version ();
printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion); printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion);
// Try to open the NFC reader
pnd = nfc_open(context, NULL);
if (pnd == NULL) { if (pnd == NULL) {
ERR("Unable to open NFC device"); ERR("Unable to connect to NFC device");
nfc_exit(context); return EXIT_FAILURE;
exit(EXIT_FAILURE);
} }
printf("NFC device: %s opened\n", nfc_device_get_name(pnd)); printf ("Connected to NFC device: %s\n", pnd->acName);
// Notes for ISO14443-A emulated tags:
// * Only short UIDs are supported
// If your UID is longer it will be truncated
// Therefore e.g. an UltraLight can only have short UID, which is
// typically badly handled by readers who still try to send their "0x95"
// * First byte of UID will be masked by 0x08 by the PN53x firmware
// as security countermeasure against real UID emulation
// Example of a Mifare Classic Mini // Example of a Mifare Classic Mini
// Note that crypto1 is not implemented in this example // Note that crypto1 is not implemented in this example
nfc_target nt = { nfc_target_t nt = {
.nm = { .nm.nmt = NMT_ISO14443A,
.nmt = NMT_ISO14443A, .nm.nbr = NBR_UNDEFINED,
.nbr = NBR_UNDEFINED, .nti.nai.abtAtqa = { 0x00, 0x04 },
}, .nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef },
.nti = { .nti.nai.btSak = 0x09,
.nai = { .nti.nai.szUidLen = 4,
.abtAtqa = { 0x00, 0x04 }, .nti.nai.szAtsLen = 0,
.abtUid = { 0x08, 0xab, 0xcd, 0xef },
.btSak = 0x09,
.szUidLen = 4,
.szAtsLen = 0,
},
},
}; };
/* /*
// Example of a FeliCa // Example of a FeliCa
nfc_target nt = { nfc_target_t nt = {
.nm = { .nm.nmt = NMT_FELICA,
.nmt = NMT_FELICA, .nm.nbr = NBR_UNDEFINED,
.nbr = NBR_UNDEFINED, .nti.nfi.abtId = { 0x01, 0xFE, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF },
}, .nti.nfi.abtPad = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF },
.nti = { .nti.nfi.abtSysCode = { 0xFF, 0xFF },
.nfi = {
.abtId = { 0x01, 0xFE, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF },
.abtPad = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF },
.abtSysCode = { 0xFF, 0xFF },
},
},
}; };
*/ */
/* /*
// Example of a ISO14443-4 (DESfire) // Example of a ISO14443-4 (DESfire)
nfc_target nt = { nfc_target_t nt = {
.nm = { .nm.nmt = NMT_ISO14443A,
.nmt = NMT_ISO14443A, .nm.nbr = NBR_UNDEFINED,
.nbr = NBR_UNDEFINED, .nti.nai.abtAtqa = { 0x03, 0x44 },
}, .nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef },
.nti = { .nti.nai.btSak = 0x20,
.nai = { .nti.nai.szUidLen = 4,
.abtAtqa = { 0x03, 0x44 }, .nti.nai.abtAts = { 0x75, 0x77, 0x81, 0x02, 0x80 },
.abtUid = { 0x08, 0xab, 0xcd, 0xef }, .nti.nai.szAtsLen = 5,
.btSak = 0x20,
.szUidLen = 4,
.abtAts = { 0x75, 0x77, 0x81, 0x02, 0x80 },
.szAtsLen = 5,
},
},
}; };
*/ */
printf("%s will emulate this ISO14443-A tag:\n", argv[0]); printf ("%s will emulate this ISO14443-A tag:\n", argv[0]);
print_nfc_target(&nt, true); print_nfc_iso14443a_info( nt.nti.nai, false );
// Switch off NP_EASY_FRAMING if target is not ISO14443-4 printf ("NFC device (configured as target) is now emulating the tag, please touch it with a second NFC device (initiator)\n");
if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, (nt.nti.nai.btSak & SAK_ISO14443_4_COMPLIANT)) < 0) { if (!nfc_target_emulate_tag (pnd, &nt)) {
nfc_perror(pnd, "nfc_target_emulate_tag"); nfc_perror (pnd, "nfc_target_emulate_tag");
nfc_close(pnd); return EXIT_FAILURE;
nfc_exit(context);
exit(EXIT_FAILURE);
}
printf("NFC device (configured as target) is now emulating the tag, please touch it with a second NFC device (initiator)\n");
if (!nfc_target_emulate_tag(pnd, &nt)) {
nfc_perror(pnd, "nfc_target_emulate_tag");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
nfc_close(pnd); nfc_disconnect(pnd);
nfc_exit(context); exit (EXIT_SUCCESS);
exit(EXIT_SUCCESS);
} }

View File

@ -1,4 +1,4 @@
.TH nfc-emulate-uid 1 "June 26, 2009" "libnfc" "libnfc's examples" .TH NFC-EMULATE-UID 1 "June 26, 2009"
.SH NAME .SH NAME
nfc-emulate-uid \- NFC target emulation command line tool based on libnfc nfc-emulate-uid \- NFC target emulation command line tool based on libnfc
.SH SYNOPSIS .SH SYNOPSIS
@ -7,14 +7,14 @@ nfc-emulate-uid \- NFC target emulation command line tool based on libnfc
.RI [ UID ] .RI [ UID ]
.SH DESCRIPTION .SH DESCRIPTION
.B nfc-emulate-uid .B nfc-emulate-uid
is a tag emulation tool that allows one to choose any tag UID. Tag emulation is one is a tag emulation tool that allows to choose any tag UID. Tag emulation is one
of the main added features in NFC. But to avoid abuse of existing systems, of the main added features in NFC. But to avoid abuse of existing systems,
manufacturers of the NFC controller intentionally did not support emulation of manufacturers of the NFC controller intentionally did not support emulation of
fully customized UID but only of "random" UIDs, which always start with 0x08. fully customized UID but only of "random" UIDs, which always start with 0x08.
The nfc-emulate-uid tool demonstrates that this can still be done using The nfc-emulate-uid tool demonstrates that this can still be done using
transmission of raw frames, and the desired UID can be optionally specified. transmission of raw frames, and the desired UID can be optionally specified.
This makes it a serious threat for security systems that rely only on the This makes it a serious thread for security systems that rely only on the
uniqueness of the UID. uniqueness of the UID.
Unfortunately, this example can't directly start in fully customisable Unfortunately, this example can't directly start in fully customisable
@ -52,17 +52,13 @@ bug, this problem is due to ACR122's internal MCU in front of NFC chip (PN532).
.SH BUGS .SH BUGS
Please report any bugs on the Please report any bugs on the
.B libnfc .B libnfc
issue tracker at: forum at
.br .BR http://www.libnfc.org/community/ "."
.BR https://github.com/nfc-tools/libnfc/issues
.SH LICENCE .SH LICENCE
.B libnfc .B libnfc
is licensed under the GNU Lesser General Public License (LGPL), version 3.
.br
.B libnfc-utils
and and
.B libnfc-examples .B libnfc-examples
are covered by the the BSD 2-Clause license. are covered by the GNU Lesser General Public License (LGPL), version 3.
.SH AUTHORS .SH AUTHORS
Roel Verdult <roel@libnfc.org> Roel Verdult <roel@libnfc.org>
.PP .PP

View File

@ -1,19 +1,13 @@
/*- /*-
* Free/Libre Near Field Communication (NFC) library * Public platform independent Near Field Communication (NFC) library examples
* *
* Libnfc historical contributors: * Copyright (C) 2009, Roel Verdult
* Copyright (C) 2009 Roel Verdult * Copyright (C) 2010, Romuald Conty
* Copyright (C) 2009-2013 Romuald Conty *
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice, * 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright * 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
@ -29,7 +23,7 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* Note that this license only applies on the examples, NFC library itself is under LGPL * Note that this license only applies on the examples, NFC library itself is under LGPL
* *
*/ */
@ -37,7 +31,7 @@
/** /**
* @file nfc-emulate-uid.c * @file nfc-emulate-uid.c
* @brief Emulates a tag which which have a "really" custom UID * @brief Emulates a tag which which have a "really" custom UID
* *
* NFC devices are able to emulate passive tags but manufacturers restrict the * NFC devices are able to emulate passive tags but manufacturers restrict the
* customization of UID. With PN53x, UID is only 4-byte long and the first * customization of UID. With PN53x, UID is only 4-byte long and the first
* byte of emulated UID is hard-wired to 0x08 which is the standard way to say * byte of emulated UID is hard-wired to 0x08 which is the standard way to say
@ -58,48 +52,45 @@
#include <nfc/nfc.h> #include <nfc/nfc.h>
#include "utils/nfc-utils.h" #include <nfc/nfc-messages.h>
#include "nfc-utils.h"
#define MAX_FRAME_LEN 264 #define MAX_FRAME_LEN 264
static uint8_t abtRecv[MAX_FRAME_LEN]; static byte_t abtRecv[MAX_FRAME_LEN];
static int szRecvBits; static size_t szRecvBits;
static nfc_device *pnd; static nfc_device_t *pnd;
static nfc_context *context;
// ISO14443A Anti-Collision response // ISO14443A Anti-Collision response
uint8_t abtAtqa[2] = { 0x04, 0x00 }; byte_t abtAtqa[2] = { 0x04, 0x00 };
uint8_t abtUidBcc[5] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x22 }; byte_t abtUidBcc[5] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x62 };
uint8_t abtSak[9] = { 0x08, 0xb6, 0xdd }; byte_t abtSak[9] = { 0x08, 0xb6, 0xdd };
static void void
intr_hdlr(int sig) intr_hdlr (void)
{ {
(void) sig; printf ("\nQuitting...\n");
if (pnd != NULL) { if (pnd != NULL) {
printf("\nAborting current command...\n"); nfc_disconnect(pnd);
nfc_abort_command(pnd);
nfc_close(pnd);
} }
nfc_exit(context); exit (EXIT_FAILURE);
exit(EXIT_SUCCESS);
} }
static void void
print_usage(char *argv[]) print_usage (char *argv[])
{ {
printf("Usage: %s [OPTIONS] [UID]\n", argv[0]); printf ("Usage: %s [OPTIONS] [UID]\n", argv[0]);
printf("Options:\n"); printf ("Options:\n");
printf("\t-h\tHelp. Print this message.\n"); printf ("\t-h\tHelp. Print this message.\n");
printf("\t-q\tQuiet mode. Silent output: received and sent frames will not be shown (improves timing).\n"); printf ("\t-q\tQuiet mode. Silent output: received and sent frames will not be shown (improves timing).\n");
printf("\n"); printf ("\n");
printf("\t[UID]\tUID to emulate, specified as 8 HEX digits (default is DEADBEEF).\n"); printf ("\t[UID]\tUID to emulate, specified as 8 HEX digits (default is DEADBEEF).\n");
} }
int int
main(int argc, char *argv[]) main (int argc, char *argv[])
{ {
uint8_t *pbtTx = NULL; byte_t *pbtTx = NULL;
size_t szTxBits; size_t szTxBits;
bool quiet_output = false; bool quiet_output = false;
@ -108,136 +99,119 @@ main(int argc, char *argv[])
// Get commandline options // Get commandline options
for (arg = 1; arg < argc; arg++) { for (arg = 1; arg < argc; arg++) {
if (0 == strcmp(argv[arg], "-h")) { if (0 == strcmp (argv[arg], "-h")) {
print_usage(argv); print_usage (argv);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} else if (0 == strcmp(argv[arg], "-q")) { } else if (0 == strcmp (argv[arg], "-q")) {
printf("Quiet mode.\n"); printf ("Quiet mode.\n");
quiet_output = true; quiet_output = true;
} else if ((arg == argc - 1) && (strlen(argv[arg]) == 8)) { // See if UID was specified as HEX string } else if ((arg == argc - 1) && (strlen (argv[arg]) == 8)) { // See if UID was specified as HEX string
uint8_t abtTmp[3] = { 0x00, 0x00, 0x00 }; byte_t abtTmp[3] = { 0x00, 0x00, 0x00 };
printf("[+] Using UID: %s\n", argv[arg]); printf ("[+] Using UID: %s\n", argv[arg]);
abtUidBcc[4] = 0x00; abtUidBcc[4] = 0x00;
for (i = 0; i < 4; ++i) { for (i = 0; i < 4; ++i) {
memcpy(abtTmp, argv[arg] + i * 2, 2); memcpy (abtTmp, argv[arg] + i * 2, 2);
abtUidBcc[i] = (uint8_t) strtol((char *) abtTmp, NULL, 16); abtUidBcc[i] = (byte_t) strtol ((char *) abtTmp, NULL, 16);
abtUidBcc[4] ^= abtUidBcc[i]; abtUidBcc[4] ^= abtUidBcc[i];
} }
} else { } else {
ERR("%s is not supported option.", argv[arg]); ERR ("%s is not supported option.", argv[arg]);
print_usage(argv); print_usage (argv);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
#ifdef WIN32 #ifdef WIN32
signal(SIGINT, (void (__cdecl *)(int)) intr_hdlr); signal (SIGINT, (void (__cdecl *) (int)) intr_hdlr);
#else #else
signal(SIGINT, intr_hdlr); signal (SIGINT, (void (*)()) intr_hdlr);
#endif #endif
nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
// Try to open the NFC device // Try to open the NFC device
pnd = nfc_open(context, NULL); pnd = nfc_connect (NULL);
if (pnd == NULL) { if (pnd == NULL) {
ERR("Unable to open NFC device"); printf ("Unable to connect to NFC device\n");
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
printf("\n"); printf ("\n");
printf("NFC device: %s opened\n", nfc_device_get_name(pnd)); printf ("Connected to NFC device: %s\n", pnd->acName);
printf("[+] Try to break out the auto-emulation, this requires a second NFC device!\n"); printf ("[+] Try to break out the auto-emulation, this requires a second NFC device!\n");
printf("[+] To do this, please send any command after the anti-collision\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\" or \"nfc-list\" tool.\n"); printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" or \"nfc-list\" tool.\n");
// Note: We have to build a "fake" nfc_target in order to do exactly the same that was done before the new nfc_target_init() was introduced. // Note: We have to build a "fake" nfc_target_t in order to do exactly the same that was done before the new nfc_target_init() was introduced.
nfc_target nt = { nfc_target_t nt = {
.nm = { .nm.nmt = NMT_ISO14443A,
.nmt = NMT_ISO14443A, .nm.nbr = NBR_UNDEFINED,
.nbr = NBR_UNDEFINED, .nti.nai.abtAtqa = { 0x04, 0x00 },
}, .nti.nai.abtUid = { 0xde, 0xad, 0xbe, 0xef },
.nti = { .nti.nai.btSak = 0x20,
.nai = { .nti.nai.szUidLen = 4,
.abtAtqa = { 0x04, 0x00 }, .nti.nai.szAtsLen = 0,
.abtUid = { 0x08, 0xad, 0xbe, 0xef },
.btSak = 0x20,
.szUidLen = 4,
.szAtsLen = 0,
},
},
}; };
if ((szRecvBits = nfc_target_init(pnd, &nt, abtRecv, sizeof(abtRecv), 0)) < 0) { if (!nfc_target_init (pnd, &nt, abtRecv, &szRecvBits)) {
nfc_perror(pnd, "nfc_target_init"); ERR ("Could not come out of auto-emulation, no command was received");
ERR("Could not come out of auto-emulation, no command was received");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
printf("[+] Received initiator command: "); printf ("[+] Received initiator command: ");
print_hex_bits(abtRecv, (size_t) szRecvBits); print_hex_bits (abtRecv, szRecvBits);
printf("[+] Configuring communication\n"); printf ("[+] Configuring communication\n");
if ((nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) || (nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, true) < 0)) { if (!nfc_configure (pnd, NDO_HANDLE_CRC, false) || !nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror (pnd, "nfc_configure");
nfc_close(pnd); exit (EXIT_FAILURE);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("[+] Done, the emulated tag is initialized with UID: %02X%02X%02X%02X\n\n", abtUidBcc[0], abtUidBcc[1], printf ("[+] Done, the emulated tag is initialized with UID: %02X%02X%02X%02X\n\n", abtUidBcc[0], abtUidBcc[1],
abtUidBcc[2], abtUidBcc[3]); abtUidBcc[2], abtUidBcc[3]);
while (true) { while (true) {
// Test if we received a frame // Test if we received a frame
if ((szRecvBits = nfc_target_receive_bits(pnd, abtRecv, sizeof(abtRecv), 0)) > 0) { if (nfc_target_receive_bits (pnd, abtRecv, &szRecvBits, NULL)) {
// Prepare the command to send back for the anti-collision request // Prepare the command to send back for the anti-collision request
switch (szRecvBits) { switch (szRecvBits) {
case 7: // Request or Wakeup case 7: // Request or Wakeup
pbtTx = abtAtqa; pbtTx = abtAtqa;
szTxBits = 16; szTxBits = 16;
// New anti-collsion session started // New anti-collsion session started
if (!quiet_output) if (!quiet_output)
printf("\n"); printf ("\n");
break; break;
case 16: // Select All case 16: // Select All
pbtTx = abtUidBcc; pbtTx = abtUidBcc;
szTxBits = 40; szTxBits = 40;
break; break;
case 72: // Select Tag case 72: // Select Tag
pbtTx = abtSak; pbtTx = abtSak;
szTxBits = 24; szTxBits = 24;
break; break;
default: // unknown length? default: // unknown length?
szTxBits = 0; szTxBits = 0;
break; break;
} }
if (!quiet_output) { if (!quiet_output) {
printf("R: "); printf ("R: ");
print_hex_bits(abtRecv, (size_t) szRecvBits); print_hex_bits (abtRecv, szRecvBits);
} }
// Test if we know how to respond // Test if we know how to respond
if (szTxBits) { if (szTxBits) {
// Send and print the command to the screen // Send and print the command to the screen
if (nfc_target_send_bits(pnd, pbtTx, szTxBits, NULL) < 0) { if (!nfc_target_send_bits (pnd, pbtTx, szTxBits, NULL)) {
nfc_perror(pnd, "nfc_target_send_bits"); nfc_perror (pnd, "nfc_target_send_bits");
nfc_close(pnd); exit (EXIT_FAILURE);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
if (!quiet_output) { if (!quiet_output) {
printf("T: "); printf ("T: ");
print_hex_bits(pbtTx, szTxBits); print_hex_bits (pbtTx, szTxBits);
} }
} }
} }
} }
nfc_disconnect (pnd);
exit (EXIT_SUCCESS);
} }

44
examples/nfc-list.1 Normal file
View File

@ -0,0 +1,44 @@
.TH NFC-LIST 1 "June 26, 2009"
.SH NAME
nfc-list \- List NFC targets
.SH SYNOPSIS
.B nfc-list
.SH DESCRIPTION
.B nfc-list
is a utility for listing any available tags like ISO14443-A, FeliCa, Jewel
or ISO14443-B (according to the device capabilities).
It may detect several tags at once thanks to a mechanism called anti-collision
but all types of tags don't support anti-collision and there is some physical
limitation of the number of tags the reader can discover.
This tool displays all available information at selection time.
.SH OPTIONS
\fB-v\fP, \fB--verbose\fP
Verbose mode
Tries to interpret data
.SH EXAMPLE
For an ISO/IEC 14443-A tag (i.e.Mifare DESFire):
ATQA (SENS_RES): 03 44
UID (NFCID1): 04 45 35 01 db 24 80
SAK (SEL_RES): 20
ATS (ATR): 75 77 81 02 80
.SH BUGS
Please report any bugs on the
.B libnfc
forum at
.BR http://www.libnfc.org/community/ "."
.SH LICENCE
.B libnfc
and
.B libnfc-examples
are covered by the GNU Lesser General Public License (LGPL), version 3.
.SH AUTHORS
Roel Verdult <roel@libnfc.org>
Romuald Conty <romuald@libnfc.org>
.PP
This manual page was written by Romuald Conty <romuald@libnfc.org>.
It is licensed under the terms of the GNU GPL (version 2 or later).

206
examples/nfc-list.c Normal file
View File

@ -0,0 +1,206 @@
/*-
* Public platform independent Near Field Communication (NFC) library examples
*
* Copyright (C) 2009, Roel Verdult
* Copyright (C) 2010, Romuald Conty, Romain Tartière
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Note that this license only applies on the examples, NFC library itself is under LGPL
*
*/
/**
* @file nfc-list.c
* @brief Lists the first target present of each founded device
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif // HAVE_CONFIG_H
#ifdef HAVE_LIBUSB
# ifdef DEBUG
# include <sys/param.h>
# include <usb.h>
# endif
#endif
#include <err.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <nfc/nfc.h>
#include <nfc/nfc-messages.h>
#include "nfc-utils.h"
#define MAX_DEVICE_COUNT 16
#define MAX_TARGET_COUNT 16
static nfc_device_t *pnd;
int
main (int argc, const char *argv[])
{
const char *acLibnfcVersion;
size_t szDeviceFound;
size_t szTargetFound;
size_t i;
bool verbose = false;
nfc_device_desc_t *pnddDevices;
// Display libnfc version
acLibnfcVersion = nfc_version ();
printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion);
pnddDevices = parse_args (argc, argv, &szDeviceFound, &verbose);
#ifdef HAVE_LIBUSB
# ifdef DEBUG
usb_set_debug (4);
# endif
#endif
/* Lazy way to open an NFC device */
#if 0
pnd = nfc_connect (NULL);
#endif
/* If specific device is wanted, i.e. an ARYGON device on /dev/ttyUSB0 */
#if 0
nfc_device_desc_t ndd;
ndd.pcDriver = "ARYGON";
ndd.pcPort = "/dev/ttyUSB0";
ndd.uiSpeed = 115200;
pnd = nfc_connect (&ndd);
#endif
/* If specific device is wanted, i.e. a SCL3711 on USB */
#if 0
nfc_device_desc_t ndd;
ndd.pcDriver = "PN533_USB";
strcpy(ndd.acDevice, "SCM Micro / SCL3711-NFC&RW");
pnd = nfc_connect (&ndd);
#endif
if (szDeviceFound == 0) {
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
fprintf (stderr, "malloc() failed\n");
return EXIT_FAILURE;
}
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szDeviceFound);
}
if (szDeviceFound == 0) {
printf ("No NFC device found.\n");
}
for (i = 0; i < szDeviceFound; i++) {
nfc_target_t ant[MAX_TARGET_COUNT];
pnd = nfc_connect (&(pnddDevices[i]));
if (pnd == NULL) {
ERR ("%s", "Unable to connect to NFC device.");
return EXIT_FAILURE;
}
nfc_initiator_init (pnd);
printf ("Connected to NFC device: %s\n", pnd->acName);
// List ISO14443A targets
nfc_modulation_t nm = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n;
if (verbose || (szTargetFound > 0)) {
printf ("%d ISO14443A passive target(s) was found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
}
for (n = 0; n < szTargetFound; n++) {
print_nfc_iso14443a_info (ant[n].nti.nai, verbose);
printf ("\n");
}
}
nm.nmt = NMT_FELICA;
nm.nbr = NBR_212;
// List Felica tags
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n;
if (verbose || (szTargetFound > 0)) {
printf ("%d Felica (212 kbps) passive target(s) was found%s\n", (int) szTargetFound,
(szTargetFound == 0) ? ".\n" : ":");
}
for (n = 0; n < szTargetFound; n++) {
print_nfc_felica_info (ant[n].nti.nfi, verbose);
printf ("\n");
}
}
nm.nbr = NBR_424;
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n;
if (verbose || (szTargetFound > 0)) {
printf ("%d Felica (424 kbps) passive target(s) was found%s\n", (int) szTargetFound,
(szTargetFound == 0) ? ".\n" : ":");
}
for (n = 0; n < szTargetFound; n++) {
print_nfc_felica_info (ant[n].nti.nfi, verbose);
printf ("\n");
}
}
nm.nmt = NMT_ISO14443B;
nm.nbr = NBR_106;
// List ISO14443B targets
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n;
if (verbose || (szTargetFound > 0)) {
printf ("%d ISO14443B passive target(s) was found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
}
for (n = 0; n < szTargetFound; n++) {
print_nfc_iso14443b_info (ant[n].nti.nbi, verbose);
printf ("\n");
}
}
nm.nmt = NMT_JEWEL;
nm.nbr = NBR_106;
// List Jewel targets
if (nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound )) {
size_t n;
if (verbose || (szTargetFound > 0)) {
printf("%d Jewel passive target(s) was found%s\n", (int)szTargetFound, (szTargetFound==0)?".\n":":");
}
for(n=0; n<szTargetFound; n++) {
print_nfc_jewel_info (ant[n].nti.nji, verbose);
printf("\n");
}
}
nfc_disconnect (pnd);
}
free (pnddDevices);
return 0;
}

64
examples/nfc-mfclassic.1 Normal file
View File

@ -0,0 +1,64 @@
.TH NFC-MFCLASSIC 1 "Nov 02, 2009"
.SH NAME
nfc-mfclassic \- MIFARE Classic command line tool
.SH SYNOPSIS
.B nfc-mfclassic
.RI \fR\fBr\fR|\fBw\fR
.RI \fR\fBa\fR|\fBb\fR
.IR DUMP
.IR [KEYS]
.SH DESCRIPTION
.B nfc-mfclassic
is a MIFARE Classic tool that allow to read or write
.IR DUMP
file using Mifare keys provided in
.IR KEYS
file.
MIFARE Classic tag is one of the most widely used RFID tags.
The firmware in the NFC controller supports authenticating, reading and writing
to/from Mifare Classic tags. This tool demonstrates the speed of this library
and its ease-of-use. It's possible to read and write the complete content of a
Mifare Classic 4KB tag within 1 second. It uses a binary Mifare Dump file (MFD)
to store the keys and data for all sectors.
Be cautious that some parts of a Mifare Classic memory are used for r/w access
of the rest of the memory, so please read the tag documentation before experimenting too much!
.SH OPTIONS
.BR r " | " w
Perform read from (
.B r
) or write to (
.B w
) card.
.TP
.BR a " | " b
Use A or B Mifare keys.
.TP
.IR DUMP
MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)
.TP
.IR KEYS
MiFare Dump (MFD) that contains the keys (optional). Data part of the dump is ignored.
.SH BUGS
Please report any bugs on the
.B libnfc
forum at
.BR http://www.libnfc.org/community/ "."
.SH LICENCE
.B libnfc
and
.B libnfc-examples
are covered by the GNU Lesser General Public License (LGPL), version 3.
.SH AUTHORS
Roel Verdult <roel@libnfc.org>
Romuald Conty <romuald@libnfc.org>
Romain Tartière <romain@blogreen.org>
.PP
This manual page was written by Romuald Conty <romuald@libnfc.org>.
It is licensed under the terms of the GNU GPL (version 2 or later).

549
examples/nfc-mfclassic.c Normal file
View File

@ -0,0 +1,549 @@
/*-
* Public platform independent Near Field Communication (NFC) library examples
*
* Copyright (C) 2009, Roel Verdult
* Copyright (C) 2010, Romuald Conty, Romain Tartière
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Note that this license only applies on the examples, NFC library itself is under LGPL
*
*/
/**
* @file nfc-mfclassic.c
* @brief MIFARE Classic manipulation example
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif // HAVE_CONFIG_H
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include <nfc/nfc.h>
#include "mifare.h"
#include "nfc-utils.h"
static nfc_device_t *pnd;
static nfc_target_t nt;
static mifare_param mp;
static mifare_classic_tag mtKeys;
static mifare_classic_tag mtDump;
static bool bUseKeyA;
static bool bUseKeyFile;
static uint8_t uiBlocks;
static byte_t keys[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5,
0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd,
0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a,
0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xab, 0xcd, 0xef, 0x12, 0x34, 0x56
};
static const nfc_modulation_t nmMifare = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
static size_t num_keys = sizeof (keys) / 6;
static void
print_success_or_failure (bool bFailure, uint32_t * uiBlockCounter)
{
printf ("%c", (bFailure) ? 'x' : '.');
if (uiBlockCounter && !bFailure)
*uiBlockCounter += (*uiBlockCounter < 128) ? 4 : 16;
}
static bool
is_first_block (uint32_t uiBlock)
{
// Test if we are in the small or big sectors
if (uiBlock < 128)
return ((uiBlock) % 4 == 0);
else
return ((uiBlock) % 16 == 0);
}
static bool
is_trailer_block (uint32_t uiBlock)
{
// Test if we are in the small or big sectors
if (uiBlock < 128)
return ((uiBlock + 1) % 4 == 0);
else
return ((uiBlock + 1) % 16 == 0);
}
static uint32_t
get_trailer_block (uint32_t uiFirstBlock)
{
// Test if we are in the small or big sectors
uint32_t trailer_block = 0;
if (uiFirstBlock < 128) {
trailer_block = uiFirstBlock + (3 - (uiFirstBlock % 4));
} else {
trailer_block = uiFirstBlock + (15 - (uiFirstBlock % 16));
}
return trailer_block;
}
static bool
authenticate (uint32_t uiBlock)
{
mifare_cmd mc;
uint32_t uiTrailerBlock;
size_t key_index;
// Key file authentication.
if (bUseKeyFile) {
// Set the authentication information (uid)
memcpy (mp.mpa.abtUid, nt.nti.nai.abtUid, 4);
// Locate the trailer (with the keys) used for this sector
uiTrailerBlock = get_trailer_block (uiBlock);
// Determin if we should use the a or the b key
if (bUseKeyA) {
mc = MC_AUTH_A;
memcpy (mp.mpa.abtKey, mtKeys.amb[uiTrailerBlock].mbt.abtKeyA, 6);
} else {
mc = MC_AUTH_B;
memcpy (mp.mpa.abtKey, mtKeys.amb[uiTrailerBlock].mbt.abtKeyB, 6);
}
// Try to authenticate for the current sector
if (nfc_initiator_mifare_cmd (pnd, mc, uiBlock, &mp))
return true;
}
// Auto authentication.
else {
// Determin if we should use the a or the b key
mc = (bUseKeyA) ? MC_AUTH_A : MC_AUTH_B;
// Set the authentication information (uid)
memcpy (mp.mpa.abtUid, nt.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 (pnd, mc, uiBlock, &mp)) {
if (bUseKeyA)
memcpy (mtKeys.amb[uiBlock].mbt.abtKeyA, &mp.mpa.abtKey, 6);
else
memcpy (mtKeys.amb[uiBlock].mbt.abtKeyB, &mp.mpa.abtKey, 6);
return true;
}
nfc_initiator_select_passive_target (pnd, nmMifare, mp.mpa.abtUid, 4, NULL);
}
}
return false;
}
static bool
read_card (void)
{
int32_t iBlock;
bool bFailure = false;
uint32_t uiReadBlocks = 0;
printf ("Reading out %d blocks |", uiBlocks + 1);
// Read the card from end to begin
for (iBlock = uiBlocks; iBlock >= 0; iBlock--) {
// Authenticate everytime we reach a trailer block
if (is_trailer_block (iBlock)) {
// Skip this the first time, bFailure it means nothing (yet)
if (iBlock != uiBlocks)
print_success_or_failure (bFailure, &uiReadBlocks);
// Show if the readout went well
if (bFailure) {
// When a failure occured we need to redo the anti-collision
if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
printf ("!\nError: tag was removed\n");
return false;
}
bFailure = false;
}
fflush (stdout);
// Try to authenticate for the current sector
if (!authenticate (iBlock)) {
printf ("!\nError: authentication failed for block 0x%02x\n", iBlock);
return false;
}
// Try to read out the trailer
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);
memcpy (mtDump.amb[iBlock].mbt.abtAccessBits, mp.mpd.abtData + 6, 4);
memcpy (mtDump.amb[iBlock].mbt.abtKeyB, mtKeys.amb[iBlock].mbt.abtKeyB, 6);
} else {
printf ("!\nError: unable to read trailer block 0x%02x\n", iBlock);
}
} else {
// Make sure a earlier readout did not fail
if (!bFailure) {
// Try to read out the data block
if (nfc_initiator_mifare_cmd (pnd, MC_READ, iBlock, &mp)) {
memcpy (mtDump.amb[iBlock].mbd.abtData, mp.mpd.abtData, 16);
} else {
bFailure = true;
printf ("!\nError: unable to read block 0x%02x\n", iBlock);
return false;
}
}
}
}
print_success_or_failure (bFailure, &uiReadBlocks);
printf ("|\n");
printf ("Done, %d of %d blocks read.\n", uiReadBlocks, uiBlocks + 1);
fflush (stdout);
return true;
}
static bool
write_card (void)
{
uint32_t uiBlock;
bool bFailure = false;
uint32_t uiWriteBlocks = 0;
printf ("Writing %d blocks |", uiBlocks + 1);
// Write the card from begin to end;
for (uiBlock = 0; uiBlock <= uiBlocks; uiBlock++) {
// Authenticate everytime we reach the first sector of a new block
if (is_first_block (uiBlock)) {
// Skip this the first time, bFailure it means nothing (yet)
if (uiBlock != 0)
print_success_or_failure (bFailure, &uiWriteBlocks);
// Show if the readout went well
if (bFailure) {
// When a failure occured we need to redo the anti-collision
if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
printf ("!\nError: tag was removed\n");
return false;
}
bFailure = false;
}
fflush (stdout);
// Try to authenticate for the current sector
if (!authenticate (uiBlock)) {
printf ("!\nError: authentication failed for block %02x\n", uiBlock);
return false;
}
}
if (is_trailer_block (uiBlock)) {
// Copy the keys over from our key dump and store the retrieved access bits
memcpy (mp.mpd.abtData, mtDump.amb[uiBlock].mbt.abtKeyA, 6);
memcpy (mp.mpd.abtData + 6, mtDump.amb[uiBlock].mbt.abtAccessBits, 4);
memcpy (mp.mpd.abtData + 10, mtDump.amb[uiBlock].mbt.abtKeyB, 6);
// Try to write the trailer
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
if (uiBlock == 0)
continue;
// Make sure a earlier write did not fail
if (!bFailure) {
// Try to write the data block
memcpy (mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, 16);
if (!nfc_initiator_mifare_cmd (pnd, MC_WRITE, uiBlock, &mp))
bFailure = true;
}
}
}
print_success_or_failure (bFailure, &uiWriteBlocks);
printf ("|\n");
printf ("Done, %d of %d blocks written.\n", uiWriteBlocks, uiBlocks + 1);
fflush (stdout);
return true;
}
static void
mifare_classic_extract_payload (const char *abDump, char *pbPayload)
{
uint8_t uiSectorIndex;
uint8_t uiBlockIndex;
size_t szDumpOffset;
size_t szPayloadIndex = 0;
for (uiSectorIndex = 1; uiSectorIndex < 16; uiSectorIndex++) {
for (uiBlockIndex = 0; uiBlockIndex < 3; uiBlockIndex++) {
szDumpOffset = uiSectorIndex * 16 * 4 + uiBlockIndex * 16;
// for(uint8_t uiByteIndex=0; uiByteIndex<16; uiByteIndex++) printf("%02x ", abDump[szPayloadIndex+uiByteIndex]);
memcpy (pbPayload + szPayloadIndex, abDump + szDumpOffset, 16);
szPayloadIndex += 16;
}
}
}
typedef enum {
ACTION_READ,
ACTION_WRITE,
ACTION_EXTRACT,
ACTION_USAGE
} action_t;
static void
print_usage (const char *pcProgramName)
{
printf ("Usage: ");
printf ("%s r|w a|b <dump.mfd> [<keys.mfd>]\n", pcProgramName);
printf (" r|w - Perform read from (r) or write to (w) card\n");
printf (" a|b - Use A or B keys for action\n");
printf (" <dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
printf (" <keys.mfd> - MiFare Dump (MFD) that contain the keys (optional)\n");
printf ("Or: ");
printf ("%s x <dump.mfd> <payload.bin>\n", pcProgramName);
printf (" x - Extract payload (data blocks) from MFD\n");
printf (" <dump.mfd> - MiFare Dump (MFD) that contains wanted payload\n");
printf (" <payload.bin> - Binary file where payload will be extracted\n");
}
int
main (int argc, const char *argv[])
{
bool b4K;
action_t atAction = ACTION_USAGE;
byte_t *pbtUID;
FILE *pfKeys = NULL;
FILE *pfDump = NULL;
const char *command = argv[1];
if (argc < 2) {
print_usage (argv[0]);
exit (EXIT_FAILURE);
}
if (strcmp (command, "r") == 0) {
atAction = ACTION_READ;
bUseKeyA = tolower ((int) ((unsigned char) *(argv[2]))) == 'a';
bUseKeyFile = (argc > 4);
} else if (strcmp (command, "w") == 0) {
atAction = ACTION_WRITE;
bUseKeyA = tolower ((int) ((unsigned char) *(argv[2]))) == 'a';
bUseKeyFile = (argc > 4);
} else if (strcmp (command, "x") == 0) {
atAction = ACTION_EXTRACT;
}
switch (atAction) {
case ACTION_USAGE:
print_usage (argv[0]);
exit (EXIT_FAILURE);
break;
case ACTION_READ:
case ACTION_WRITE:
if (argc < 4) {
print_usage (argv[0]);
exit (EXIT_FAILURE);
}
if (bUseKeyFile) {
pfKeys = fopen (argv[4], "rb");
if (pfKeys == NULL) {
printf ("Could not open keys file: %s\n", argv[4]);
exit (EXIT_FAILURE);
}
if (fread (&mtKeys, 1, sizeof (mtKeys), pfKeys) != sizeof (mtKeys)) {
printf ("Could not read keys file: %s\n", argv[4]);
fclose (pfKeys);
exit (EXIT_FAILURE);
}
fclose (pfKeys);
}
if (atAction == ACTION_READ) {
memset (&mtDump, 0x00, sizeof (mtDump));
} else {
pfDump = fopen (argv[3], "rb");
if (pfDump == NULL) {
printf ("Could not open dump file: %s\n", argv[3]);
exit (EXIT_FAILURE);
}
if (fread (&mtDump, 1, sizeof (mtDump), pfDump) != sizeof (mtDump)) {
printf ("Could not read dump file: %s\n", argv[3]);
fclose (pfDump);
exit (EXIT_FAILURE);
}
fclose (pfDump);
}
// printf("Successfully opened required files\n");
// Try to open the NFC reader
pnd = nfc_connect (NULL);
if (pnd == NULL) {
printf ("Error connecting NFC reader\n");
exit (EXIT_FAILURE);
}
nfc_initiator_init (pnd);
// Drop the field for a while
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
nfc_perror (pnd, "nfc_configure");
exit (EXIT_FAILURE);
}
// Let the reader only try once to find a tag
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
nfc_perror (pnd, "nfc_configure");
exit (EXIT_FAILURE);
}
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
nfc_perror (pnd, "nfc_configure");
exit (EXIT_FAILURE);
}
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
nfc_perror (pnd, "nfc_configure");
exit (EXIT_FAILURE);
}
// Enable field so more power consuming cards can power themselves up
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
nfc_perror (pnd, "nfc_configure");
exit (EXIT_FAILURE);
}
// Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance.
nfc_configure (pnd, NDO_AUTO_ISO14443_4, false);
printf ("Connected to NFC reader: %s\n", pnd->acName);
// Try to find a MIFARE Classic tag
if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
printf ("Error: no tag was found\n");
nfc_disconnect (pnd);
exit (EXIT_FAILURE);
}
// Test if we are dealing with a MIFARE compatible tag
if ((nt.nti.nai.btSak & 0x08) == 0) {
printf ("Error: tag is not a MIFARE Classic card\n");
nfc_disconnect (pnd);
exit (EXIT_FAILURE);
}
if (bUseKeyFile) {
// Get the info from the key dump
b4K = (mtKeys.amb[0].mbm.abtATQA[1] == 0x02);
pbtUID = mtKeys.amb[0].mbm.abtUID;
// Compare if key dump UID is the same as the current tag UID
if (memcmp (nt.nti.nai.abtUid, pbtUID, 4) != 0) {
printf ("Expected MIFARE Classic %ck card with UID: %02x%02x%02x%02x\n", b4K ? '4' : '1', pbtUID[3], pbtUID[2],
pbtUID[1], pbtUID[0]);
}
}
// Get the info from the current tag
pbtUID = nt.nti.nai.abtUid;
b4K = (nt.nti.nai.abtAtqa[1] == 0x02);
printf ("Found MIFARE Classic %ck card with UID: %02x%02x%02x%02x\n", b4K ? '4' : '1', pbtUID[3], pbtUID[2],
pbtUID[1], pbtUID[0]);
uiBlocks = (b4K) ? 0xff : 0x3f;
if (atAction == ACTION_READ) {
if (read_card ()) {
printf ("Writing data to file: %s ...", argv[3]);
fflush (stdout);
pfDump = fopen (argv[3], "wb");
if (fwrite (&mtDump, 1, sizeof (mtDump), pfDump) != sizeof (mtDump)) {
printf ("\nCould not write to file: %s\n", argv[3]);
exit (EXIT_FAILURE);
}
printf ("Done.\n");
fclose (pfDump);
}
} else {
write_card ();
}
nfc_disconnect (pnd);
break;
case ACTION_EXTRACT:{
const char *pcDump = argv[2];
const char *pcPayload = argv[3];
FILE *pfDump = NULL;
FILE *pfPayload = NULL;
char abDump[4096];
char abPayload[4096];
pfDump = fopen (pcDump, "rb");
if (pfDump == NULL) {
printf ("Could not open dump file: %s\n", pcDump);
exit (EXIT_FAILURE);
}
if (fread (abDump, 1, sizeof (abDump), pfDump) != sizeof (abDump)) {
printf ("Could not read dump file: %s\n", pcDump);
fclose (pfDump);
exit (EXIT_FAILURE);
}
fclose (pfDump);
mifare_classic_extract_payload (abDump, abPayload);
printf ("Writing data to file: %s\n", pcPayload);
pfPayload = fopen (pcPayload, "wb");
if (fwrite (abPayload, 1, sizeof (abPayload), pfPayload) != sizeof (abPayload)) {
printf ("Could not write to file: %s\n", pcPayload);
exit (EXIT_FAILURE);
}
fclose (pfPayload);
printf ("Done, all bytes have been extracted!\n");
}
};
exit (EXIT_SUCCESS);
}

View File

@ -1,40 +0,0 @@
.TH nfc-mfsetuid 1 "Sep 05, 2011" "libnfc" "NFC Utilities"
.SH NAME
nfc-mfsetuid \- MIFARE 1K special card UID setting and recovery tool
.SH SYNOPSIS
.B nfc-mfsetuid
[
.I UID
]
.SH DESCRIPTION
.B nfc-mfsetuid
is a MIFARE tool that allows setting of UID on special versions (Chinese clones) of Mifare 1K cards. It will also recover
damaged cards that have had invalid data written to block 0 (e.g. wrong BCC). Currently only 4 Byte UID is supported.
Specify an eight hex character UID or leave blank for the default '01234567'.
.SH OPTIONS
.B -f
Format. Wipe all data (set to 0xFF) and reset ACLs to defaults.
.B -q
Quiet. Suppress output of commands and responses.
.SH BUGS
Please report any bugs on the
.B libnfc
issue tracker at:
.br
.BR https://github.com/nfc-tools/libnfc/issues
.SH LICENCE
.B libnfc
is licensed under the GNU Lesser General Public License (LGPL), version 3.
.br
.B libnfc-utils
and
.B libnfc-examples
are covered by the the BSD 2-Clause license.
.SH AUTHORS
Adam Laurie <adam@algroup.co.uk>
.PP
This manual page was written by Adam Laurie <adam@algroup.co.uk>.
It is licensed under the terms of the GNU GPL (version 2 or later).

Some files were not shown because too many files have changed in this diff Show More