Compare commits
347 Commits
libnfc-1.7
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 28ce753431 | |||
| 80ef76fdda | |||
|
|
42de50f2b7 | ||
|
|
5b9ae7ee51 | ||
|
|
3df7f25f11 | ||
|
|
16671bd0a3 | ||
|
|
6d0e8a5d9b | ||
|
|
a884a45ab1 | ||
|
|
c8185c9eca | ||
|
|
56f6bd4fbb | ||
|
|
1b8c244e38 | ||
|
|
fb290be070 | ||
|
|
a9cb26b28f | ||
|
|
c924e5e00c | ||
|
|
ba14d10e79 | ||
|
|
9a94f20050 | ||
|
|
180fbabfe1 | ||
|
|
1dc9dcb664 | ||
|
|
1f4d2fb3d4 | ||
|
|
2b5ad9ce0b | ||
|
|
7ebf9b92d6 | ||
|
|
3af2e14acc | ||
|
|
b5180a6a70 | ||
|
|
0cd314c514 | ||
|
|
c3f739dea3 | ||
|
|
126cf9c1be | ||
|
|
d9a04a54ff | ||
|
|
cc4311acab | ||
|
|
e37d24e691 | ||
|
|
1077228fbd | ||
|
|
5c09dc180a | ||
|
|
d5fcd08d41 | ||
|
|
f56bbabf6c | ||
|
|
9cece8b55d | ||
|
|
7ad18a2120 | ||
|
|
e21fab3685 | ||
|
|
82f23c411d | ||
|
|
66d3560608 | ||
|
|
fc51c8662b | ||
|
|
db081ed12d | ||
|
|
6fb61d3c1e | ||
|
|
f2677da74c | ||
|
|
0bf4cec661 | ||
|
|
0de55961c4 | ||
|
|
c8fcaea8ab | ||
|
|
6921e57fb8 | ||
|
|
01bc5693d9 | ||
|
|
db957aabdf | ||
|
|
f7b9b0eafa | ||
|
|
709ef8381f | ||
|
|
3c55b8746b | ||
|
|
02f0f6b290 | ||
|
|
7a5e654309 | ||
|
|
2b21d87e8e | ||
|
|
4e922e8194 | ||
|
|
3f4b7a037a | ||
|
|
dd96571f88 | ||
|
|
5a87f1f3db | ||
|
|
7b6ff73c4b | ||
|
|
e560689f60 | ||
|
|
a28a537610 | ||
|
|
4b7791f845 | ||
|
|
1f6f75af38 | ||
|
|
435e2ffc81 | ||
|
|
874d9605aa | ||
|
|
53eccd4be4 | ||
|
|
b02f94d7da | ||
|
|
f02ff51449 | ||
|
|
5c3c468a6a | ||
|
|
63cf0acb0b | ||
|
|
5294c0290f | ||
|
|
fa78e8b883 | ||
|
|
357ae384af | ||
|
|
c8692aa239 | ||
|
|
91d7c5d32f | ||
|
|
4525cd1c32 | ||
|
|
f52d04e0a7 | ||
|
|
5a059db901 | ||
|
|
730f705c0d | ||
|
|
6b4f6249bd | ||
|
|
d29b3170d9 | ||
|
|
4a2c764961 | ||
|
|
020f5317a6 | ||
|
|
675c30eb93 | ||
|
|
beb8fdd759 | ||
|
|
6f41ea3ad3 | ||
|
|
8352c80679 | ||
|
|
66176016ed | ||
|
|
f1bb27d1af | ||
|
|
c884f36b94 | ||
|
|
17e615e8b1 | ||
|
|
a07d879496 | ||
|
|
10f880374c | ||
|
|
96568a1023 | ||
|
|
dcc52cd4d5 | ||
|
|
19a51dc2bd | ||
|
|
61e93c1cdf | ||
|
|
cbc4e7b5c4 | ||
|
|
692038ceaf | ||
|
|
f3f588671c | ||
|
|
fbae17186b | ||
|
|
004eff8e96 | ||
|
|
7908d405dd | ||
|
|
ff4e1efa7b | ||
|
|
c34c446831 | ||
|
|
54ba7359ce | ||
|
|
fba969472d | ||
|
|
a85f003d91 | ||
|
|
8a1e14901d | ||
|
|
2a6a8e6e29 | ||
|
|
07f918283b | ||
|
|
6e035c33f3 | ||
|
|
a77a2a8497 | ||
|
|
6f793da1c1 | ||
|
|
8e7a8e1b61 | ||
|
|
959a992a81 | ||
|
|
75e5e23c81 | ||
|
|
f8b28523d7 | ||
|
|
ad695d0a18 | ||
|
|
454a8c4d70 | ||
|
|
fbdbe6eff3 | ||
|
|
c109d37783 | ||
|
|
141907e127 | ||
|
|
48d5f6b666 | ||
|
|
a4af2be66c | ||
|
|
91f7db5b4d | ||
|
|
ebb13d8965 | ||
|
|
c42e2502d4 | ||
|
|
c59219905c | ||
|
|
ae56188005 | ||
|
|
a9e4c915f2 | ||
|
|
793d5adde6 | ||
|
|
7ca85a02de | ||
|
|
85100c0aae | ||
|
|
ddfe2e648a | ||
|
|
2418d946a3 | ||
|
|
b5641f8562 | ||
|
|
f93169feb4 | ||
|
|
c52cdb10c8 | ||
|
|
4ae4cc86f8 | ||
|
|
980513f4d1 | ||
|
|
d11db46ddd | ||
|
|
a9af1927e6 | ||
|
|
25ee3a2f76 | ||
|
|
3ba065f00b | ||
|
|
40b54a10d7 | ||
|
|
2229b9ed69 | ||
|
|
4c914e67e5 | ||
|
|
7c9a2a8062 | ||
|
|
62f27c1c58 | ||
|
|
7a0a469c8a | ||
|
|
df4f9c0fbd | ||
|
|
e4ca7f45d2 | ||
|
|
216145fba5 | ||
|
|
2b96c9f3c5 | ||
|
|
2869ae2eb8 | ||
|
|
f9417586c0 | ||
|
|
14f48d0122 | ||
|
|
00700bc66d | ||
|
|
dcdbff0705 | ||
|
|
9f1a68530a | ||
|
|
9f4290b61b | ||
|
|
c9ac17c9f5 | ||
|
|
1bf542b9e2 | ||
|
|
767abe50e2 | ||
|
|
38164c49ef | ||
|
|
c958b2c25d | ||
|
|
a06bfe50a5 | ||
|
|
6235a8a26b | ||
|
|
b59f8fb3b4 | ||
|
|
fead8d6849 | ||
|
|
e41a42cf96 | ||
|
|
024fca9cb7 | ||
|
|
3ec9ecf800 | ||
|
|
560f6a6413 | ||
|
|
abae2bb17b | ||
|
|
f2457d0559 | ||
|
|
a9f3e3a2ac | ||
|
|
963eb074ec | ||
|
|
c04dd91e98 | ||
|
|
fe04b85678 | ||
|
|
3f8bb59f1e | ||
|
|
ca96e50e9b | ||
|
|
32bb627108 | ||
|
|
86ce8dff52 | ||
|
|
b65674a8e3 | ||
|
|
2d2a664f6c | ||
|
|
9ccfba2125 | ||
|
|
787382f4d5 | ||
|
|
b7ae7cb5fd | ||
|
|
6c44c20ffc | ||
|
|
c51caf424a | ||
|
|
e119296680 | ||
|
|
bf31594410 | ||
|
|
04ef5ca902 | ||
|
|
2033519b0c | ||
|
|
f2c264d4ae | ||
|
|
05220537ea | ||
|
|
c815c7a059 | ||
|
|
9a749e1a66 | ||
|
|
e4df2f3334 | ||
|
|
f184407cc5 | ||
|
|
e8d44f1ee8 | ||
|
|
4e4438435d | ||
|
|
02c06c8e28 | ||
|
|
047379406e | ||
|
|
be1b897617 | ||
|
|
15c31aecdb | ||
|
|
ff37cdb2be | ||
|
|
99a7d9aa35 | ||
|
|
c5e8adc169 | ||
|
|
646ab57ace | ||
|
|
db4433f116 | ||
|
|
7e3a7a6d05 | ||
|
|
732a282190 | ||
|
|
d808802b16 | ||
|
|
b86b7efb10 | ||
|
|
11bcf05a75 | ||
|
|
e26fe912fd | ||
|
|
20a1b978f3 | ||
|
|
968f59a988 | ||
|
|
e50b18848f | ||
|
|
372bf37eec | ||
|
|
295c70911a | ||
|
|
f16aeda9d0 | ||
|
|
7991c7d60c | ||
|
|
84c3e8a3ba | ||
|
|
11a2da2811 | ||
|
|
f9f03fa7fa | ||
|
|
8e5ec4acf3 | ||
|
|
e0c72b782f | ||
|
|
3592a60c1d | ||
|
|
9c7b9eda8c | ||
|
|
b38597f1e0 | ||
|
|
e9a750fc00 | ||
|
|
e32cc068ec | ||
|
|
b29332a309 | ||
|
|
e946f7a97a | ||
|
|
b2a9cce037 | ||
|
|
c3b3f64224 | ||
|
|
a07a496234 | ||
|
|
65477eea5e | ||
|
|
a625d6a02d | ||
|
|
d960673681 | ||
|
|
8f8f780c2b | ||
|
|
b953002f8f | ||
|
|
512be89700 | ||
|
|
61b42396d9 | ||
|
|
4a10d0f21b | ||
|
|
7eae55e929 | ||
|
|
0d3d5c13ff | ||
|
|
27ed3acc1a | ||
|
|
35cc69dffb | ||
|
|
4076046a66 | ||
|
|
659f5f407f | ||
|
|
41d694013c | ||
|
|
403650a0fc | ||
|
|
a4bc1b9f6c | ||
|
|
ed62b01a0f | ||
|
|
4b8871fd8f | ||
|
|
ecd0e59b5c | ||
|
|
7b1ff70a52 | ||
|
|
e1a25a8203 | ||
|
|
898f3a4d2f | ||
|
|
83b70d6326 | ||
|
|
7d4352dc98 | ||
|
|
e23f8a9f9c | ||
|
|
e37de54e18 | ||
|
|
e8e1826eeb | ||
|
|
8de7ce3899 | ||
|
|
1f68888020 | ||
|
|
291f70edee | ||
|
|
62159a33ef | ||
|
|
d63e624b09 | ||
|
|
b1a81b385d | ||
|
|
bc8bb8de89 | ||
|
|
c228396c2d | ||
|
|
10398b6bd9 | ||
|
|
24979c65cc | ||
|
|
c7f386dbcf | ||
|
|
42d455c4e7 | ||
|
|
619b476028 | ||
|
|
0cece94778 | ||
|
|
3aa2d46588 | ||
|
|
73c2ef8582 | ||
|
|
1d4720671e | ||
|
|
2046fb9461 | ||
|
|
758cb0cc05 | ||
|
|
c71d7267ac | ||
|
|
20f22b97e7 | ||
|
|
b5684c1755 | ||
|
|
87c6053d6f | ||
|
|
e7feb6587d | ||
|
|
48c271e49d | ||
|
|
53edc32a21 | ||
|
|
4193bb4873 | ||
|
|
b7f620fdab | ||
|
|
141e99959e | ||
|
|
5d2052e77f | ||
|
|
555f9ce4cf | ||
|
|
792e3d9cbd | ||
|
|
13fee61e87 | ||
|
|
09ce2233ce | ||
|
|
e72fe468a4 | ||
|
|
738970c135 | ||
|
|
c55bbec50d | ||
|
|
7ae5a0c333 | ||
|
|
17ed36a7a5 | ||
|
|
6be73720fa | ||
|
|
59f6c5de54 | ||
|
|
49dde9c28c | ||
|
|
7f23f1f84d | ||
|
|
04a51df796 | ||
|
|
68094b4f6d | ||
|
|
fecc19de4c | ||
|
|
11a4e3cd7f | ||
|
|
af8fe86b0d | ||
|
|
d028bc725d | ||
|
|
22078a8509 | ||
|
|
ef74d81a8b | ||
|
|
e96061e44b | ||
|
|
33ce39ff71 | ||
|
|
8fbedb87f5 | ||
|
|
c31f8bd9be | ||
|
|
0f77565a3c | ||
|
|
1fe7c00e48 | ||
|
|
fce491c829 | ||
|
|
f82aa75072 | ||
|
|
eeb226aceb | ||
|
|
1785ac14c2 | ||
|
|
4e823d8db0 | ||
|
|
92c5bd864b | ||
|
|
5a08fcf2bc | ||
|
|
9d82d598f0 | ||
|
|
b6a8745838 | ||
|
|
b978c45a11 | ||
|
|
bb9babbeda | ||
|
|
bd92f74a58 | ||
|
|
9a254712b5 | ||
|
|
e57dc8a746 | ||
|
|
89fc6a723e | ||
|
|
ddde2dd8f2 | ||
|
|
108de27c1b | ||
|
|
6b74323369 | ||
|
|
6ab3c368b8 | ||
|
|
db4fae9c2c | ||
|
|
7adad098c3 |
86
.gitignore
vendored
86
.gitignore
vendored
@ -1,16 +1,21 @@
|
||||
**/.deps/
|
||||
**/.libs/
|
||||
**/Makefile
|
||||
**/Makefile.in
|
||||
*.exe
|
||||
*.la
|
||||
*.lo
|
||||
*.o
|
||||
*~
|
||||
.vs/
|
||||
CMakeSettings.json
|
||||
Doxyfile
|
||||
INSTALL
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
ar-lib
|
||||
autom4te.cache/
|
||||
build
|
||||
cmake/Makefile
|
||||
cmake/Makefile.in
|
||||
cmake/modules/Makefile
|
||||
cmake/modules/Makefile.in
|
||||
compile
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
@ -18,24 +23,8 @@ config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
contrib/Makefile
|
||||
contrib/Makefile.in
|
||||
contrib/devd/Makefile
|
||||
contrib/devd/Makefile.in
|
||||
contrib/udev/Makefile
|
||||
contrib/udev/Makefile.in
|
||||
contrib/win32/Makefile
|
||||
contrib/win32/Makefile.in
|
||||
contrib/win32/sys/Makefile
|
||||
contrib/win32/sys/Makefile.in
|
||||
debian/
|
||||
depcomp
|
||||
examples/*.o
|
||||
examples/.deps/
|
||||
examples/.libs/
|
||||
examples/Makefile
|
||||
examples/Makefile.in
|
||||
examples/doc/.deps/
|
||||
examples/nfc-anticol
|
||||
examples/nfc-dep-initiator
|
||||
examples/nfc-dep-target
|
||||
@ -48,44 +37,10 @@ examples/nfc-relay
|
||||
examples/pn53x-diagnose
|
||||
examples/pn53x-sam
|
||||
examples/pn53x-tamashell
|
||||
examples/pn53x-tamashell-scripts/Makefile
|
||||
examples/pn53x-tamashell-scripts/Makefile.in
|
||||
examples/quick_start_example1
|
||||
examples/quick_start_example2
|
||||
include/Makefile
|
||||
include/Makefile.in
|
||||
include/nfc/Makefile
|
||||
include/nfc/Makefile.in
|
||||
install-sh
|
||||
libnfc.pc
|
||||
libnfc/*.lo
|
||||
libnfc/*.o
|
||||
libnfc/.deps/
|
||||
libnfc/.libs/
|
||||
libnfc/Makefile
|
||||
libnfc/Makefile.in
|
||||
libnfc/buses/*.la
|
||||
libnfc/buses/*.lo
|
||||
libnfc/buses/*.o
|
||||
libnfc/buses/.deps/
|
||||
libnfc/buses/.libs/
|
||||
libnfc/buses/Makefile
|
||||
libnfc/buses/Makefile.in
|
||||
libnfc/chips/*.la
|
||||
libnfc/chips/*.lo
|
||||
libnfc/chips/*.o
|
||||
libnfc/chips/.deps/
|
||||
libnfc/chips/.libs/
|
||||
libnfc/chips/Makefile
|
||||
libnfc/chips/Makefile.in
|
||||
libnfc/drivers/*.la
|
||||
libnfc/drivers/*.lo
|
||||
libnfc/drivers/*.o
|
||||
libnfc/drivers/.deps/
|
||||
libnfc/drivers/.libs/
|
||||
libnfc/drivers/Makefile
|
||||
libnfc/drivers/Makefile.in
|
||||
libnfc/libnfc.la
|
||||
libtool
|
||||
ltmain.sh
|
||||
m4/libtool.m4
|
||||
@ -95,21 +50,12 @@ m4/ltversion.m4
|
||||
m4/lt~obsolete.m4
|
||||
missing
|
||||
stamp-h1
|
||||
test/*.la
|
||||
test/*.lo
|
||||
test/*.o
|
||||
test/.deps/
|
||||
test/.libs/
|
||||
test/Makefile
|
||||
test/Makefile.in
|
||||
utils/*.la
|
||||
utils/*.lo
|
||||
utils/*.o
|
||||
utils/.deps/
|
||||
utils/.libs/
|
||||
utils/Makefile
|
||||
utils/Makefile.in
|
||||
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
|
||||
|
||||
81
.travis.yml
Normal file
81
.travis.yml
Normal file
@ -0,0 +1,81 @@
|
||||
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
|
||||
26
AUTHORS
26
AUTHORS
@ -2,22 +2,48 @@
|
||||
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>
|
||||
Romain Tartiere <romain.tartiere@gmail.com>
|
||||
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>
|
||||
|
||||
206
CMakeLists.txt
206
CMakeLists.txt
@ -1,8 +1,14 @@
|
||||
PROJECT(libnfc C)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
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_MINOR "7")
|
||||
SET(VERSION_PATCH "1")
|
||||
SET(VERSION_MINOR "8")
|
||||
SET(VERSION_PATCH "0")
|
||||
|
||||
SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
|
||||
|
||||
@ -12,29 +18,33 @@ SET(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
||||
|
||||
# config.h
|
||||
IF(WIN32)
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/cmake/config_windows.h.cmake ${CMAKE_CURRENT_SOURCE_DIR}/config.h)
|
||||
SET(LIBNFC_SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/config" CACHE PATH "libnfc configuration directory")
|
||||
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(SYSCONFDIR "/etc" CACHE PATH "System configuration directory")
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/cmake/config_posix.h.cmake ${CMAKE_CURRENT_SOURCE_DIR}/config.h)
|
||||
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})
|
||||
|
||||
ADD_DEFINITIONS("-DHAVE_CONFIG_H")
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
# make it easy to locate CMake modules for finding libraries
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/modules/")
|
||||
|
||||
# Options
|
||||
SET(LIBNFC_LOG ON CACHE BOOL "Enable log facility (errors, warning, info and debug messages)")
|
||||
option (LIBNFC_LOG "Enable log facility (errors, warning, info and debug messages)" ON)
|
||||
IF(LIBNFC_LOG)
|
||||
ADD_DEFINITIONS(-DLOG)
|
||||
ENDIF(LIBNFC_LOG)
|
||||
|
||||
SET(LIBNFC_ENVVARS ON CACHE BOOL "Enable envvars facility")
|
||||
option (LIBNFC_ENVVARS "Enable envvars facility" ON)
|
||||
IF(LIBNFC_ENVVARS)
|
||||
ADD_DEFINITIONS(-DENVVARS)
|
||||
ENDIF(LIBNFC_ENVVARS)
|
||||
@ -49,11 +59,17 @@ ELSE(LIBNFC_DEBUG_MODE)
|
||||
SET(WIN32_MODE "release")
|
||||
ENDIF(LIBNFC_DEBUG_MODE)
|
||||
|
||||
SET(LIBNFC_CONFFILES_MODE ON CACHE BOOL "Enable configuration files")
|
||||
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
|
||||
SET(builddir "${CMAKE_BINARY_DIR}")
|
||||
SET(top_srcdir "${CMAKE_SOURCE_DIR}")
|
||||
@ -87,12 +103,34 @@ ENDIF(CMAKE_COMPILER_IS_GNUCC)
|
||||
ADD_DEFINITIONS(-Du_int8_t=uint8_t -Du_int16_t=uint16_t)
|
||||
|
||||
IF(MINGW)
|
||||
# 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}")
|
||||
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)
|
||||
@ -103,26 +141,39 @@ IF(NOT WIN32)
|
||||
IF(LIBNFC_DRIVER_PN53X_USB)
|
||||
SET(PKG_REQ ${PKG_REQ} "libusb")
|
||||
ENDIF(LIBNFC_DRIVER_PN53X_USB)
|
||||
IF(LIBNFC_DRIVER_ACR122)
|
||||
IF(LIBNFC_DRIVER_ACR122_USB)
|
||||
SET(PKG_REQ ${PKG_REQ} "libusb")
|
||||
ENDIF(LIBNFC_DRIVER_ACR122_USB)
|
||||
IF(LIBNFC_DRIVER_PCSC)
|
||||
SET(PKG_REQ ${PKG_REQ} "libpcsclite")
|
||||
ENDIF(LIBNFC_DRIVER_ACR122)
|
||||
ENDIF(LIBNFC_DRIVER_PCSC)
|
||||
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
|
||||
STRING(REPLACE ";" "," PKG_CONFIG_REQUIRES "${PKG_REQ}")
|
||||
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)
|
||||
ENDIF(NOT WIN32)
|
||||
|
||||
# Require PCRE for Win32
|
||||
IF (WIN32)
|
||||
FIND_PACKAGE(PCRE REQUIRED)
|
||||
IF(PCRE_INCLUDE_DIRS)
|
||||
INCLUDE_DIRECTORIES(${PCRE_INCLUDE_DIRS})
|
||||
LINK_DIRECTORIES(${PCRE_LIBRARY_DIRS})
|
||||
ENDIF(PCRE_INCLUDE_DIRS)
|
||||
ENDIF(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})
|
||||
@ -137,36 +188,117 @@ ENDIF(LIBUSB_INCLUDE_DIRS)
|
||||
# version.rc for Windows
|
||||
IF(WIN32)
|
||||
# Date for filling in rc file information
|
||||
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)
|
||||
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)
|
||||
SET(RC_FILE_TYPE VFT_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(include)
|
||||
ADD_SUBDIRECTORY(utils)
|
||||
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
|
||||
IF(WIN32)
|
||||
SET(CPACK_GENERATOR "ZIP")
|
||||
ELSE(WIN32)
|
||||
SET(CPACK_GENERATOR "TBZ2")
|
||||
IF(BUILD_DEBPKG)
|
||||
SET(CPACK_GENERATOR "DEB")
|
||||
ENDIF(BUILD_DEBPKG)
|
||||
ENDIF(WIN32)
|
||||
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Near Field Communication (NFC) library")
|
||||
SET(CPACK_PACKAGE_VENDOR "Roel Verdult")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
|
||||
SET(CPACK_PACKAGE_CONTACT "Roel Verdult <roel@libnfc.org>")
|
||||
|
||||
#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_VERSION_MAJOR ${VERSION_MAJOR})
|
||||
|
||||
85
ChangeLog
85
ChangeLog
@ -1,5 +1,88 @@
|
||||
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
|
||||
|
||||
2480
Doxyfile.in
2480
Doxyfile.in
File diff suppressed because it is too large
Load Diff
54
HACKING
54
HACKING
@ -1,54 +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:
|
||||
$ 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 compatility
|
||||
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
|
||||
68
HACKING.md
Normal file
68
HACKING.md
Normal file
@ -0,0 +1,68 @@
|
||||
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
|
||||
18
Makefile.am
18
Makefile.am
@ -2,7 +2,13 @@ ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
AM_CFLAGS = $(LIBNFC_CFLAGS)
|
||||
|
||||
SUBDIRS = libnfc utils examples include contrib cmake test
|
||||
SUBDIRS = libnfc utils
|
||||
|
||||
if EXAMPLE_ENABLED
|
||||
SUBDIRS += examples
|
||||
endif
|
||||
|
||||
SUBDIRS += include contrib cmake test
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libnfc.pc
|
||||
@ -10,8 +16,12 @@ pkgconfig_DATA = libnfc.pc
|
||||
EXTRA_DIST = \
|
||||
CMakeLists.txt \
|
||||
Doxyfile \
|
||||
README-Windows.txt \
|
||||
libnfc.conf.sample
|
||||
HACKING.md \
|
||||
NEWS.md \
|
||||
README.md \
|
||||
README-Windows.md \
|
||||
libnfc.conf.sample \
|
||||
mingw-cross-compile.sh
|
||||
|
||||
CLEANFILES = Doxygen.log coverage.info libnfc.pc
|
||||
|
||||
@ -34,7 +44,7 @@ style:
|
||||
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 \
|
||||
--brackets=linux --pad-oper --unpad-paren --pad-header \
|
||||
--style=linux --pad-oper --unpad-paren --pad-header \
|
||||
--align-pointer=name {} \;
|
||||
|
||||
cppcheck:
|
||||
|
||||
@ -1,3 +1,24 @@
|
||||
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:
|
||||
166
README
166
README
@ -1,166 +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:
|
||||
* 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:
|
||||
http://libnfc.googlecode.com/
|
||||
|
||||
Important note: this file covers POSIX systems, for Windows please read README-Windows.txt
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
Some NFC drivers depend on third party software:
|
||||
|
||||
* pn53x_usb & acr122_usb:
|
||||
|
||||
- libusb-0.1 http://libusb.sf.net
|
||||
|
||||
* acr122_pcsc:
|
||||
|
||||
- pcsc-lite http://pcsclite.alioth.debian.org/
|
||||
|
||||
The regression test suite depends on the cutter framework:
|
||||
http://cutter.sf.net
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
See the file 'INSTALL' for configure, build and install details.
|
||||
|
||||
Additionnally, 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/42-pn53x.rules /lib/udev/rules.d/
|
||||
|
||||
Under FreeBSD, if you use devd, there is also a rules file: contrib/devd/pn53x.conf.
|
||||
|
||||
How to report bugs
|
||||
==================
|
||||
|
||||
To report a bug, visit http://code.google.com/p/libnfc/issues/list 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 http://code.google.com/p/libnfc/issues/list or
|
||||
can be sent directly to libnfc's developers:
|
||||
http://nfc-tools.org/index.php?title=Contact
|
||||
|
||||
If the patch fixes a bug, it is usually a good idea to include
|
||||
all the information described in "How to Report Bugs".
|
||||
|
||||
Building
|
||||
========
|
||||
|
||||
It should be as simple as running these two commands:
|
||||
|
||||
./configure
|
||||
make
|
||||
|
||||
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, two kernel-modules must not be loaded in order
|
||||
to use libnfc : "nfc" and "pn533".
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
*-
|
||||
* 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
|
||||
-*
|
||||
*-
|
||||
* 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
|
||||
============
|
||||
@ -18,10 +18,9 @@ Requirements
|
||||
- MinGW-w64 compiler toolchain [1]
|
||||
- LibUsb-Win32 1.2.5.0 (or greater) [2]
|
||||
- CMake 2.8 [3]
|
||||
- PCRE for Windows [4]
|
||||
|
||||
This was tested on Windows 7 64 bit, but should work on Windows Vista and
|
||||
Windows XP and 32 bit as well.
|
||||
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/
|
||||
@ -34,35 +33,38 @@ 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
|
||||
- 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 .
|
||||
|
||||
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"
|
||||
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
|
||||
|
||||
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.
|
||||
the tools against this shared library.
|
||||
|
||||
References
|
||||
==========
|
||||
[1] the easiest way is to use the TDM-GCC installer.
|
||||
[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
|
||||
[4] http://gnuwin32.sourceforge.net/packages/pcre.htm
|
||||
250
README.md
Normal file
250
README.md
Normal file
@ -0,0 +1,250 @@
|
||||
```
|
||||
*-
|
||||
* 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.
|
||||
@ -6,6 +6,6 @@ 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@" "@PCRE_BIN_DIRS@")
|
||||
SET(dirs "@LIBUSB_LIBRARY_DIR@")
|
||||
|
||||
fixup_bundle("${bundle}" "${other_libs}" "${dirs}")
|
||||
|
||||
34
cmake/LibNFCConfig.cmake.in
Normal file
34
cmake/LibNFCConfig.cmake.in
Normal file
@ -0,0 +1,34 @@
|
||||
# -*- 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@" )
|
||||
|
||||
31
cmake/LibNFCConfigVersion.cmake.in
Normal file
31
cmake/LibNFCConfigVersion.cmake.in
Normal file
@ -0,0 +1,31 @@
|
||||
# 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()
|
||||
@ -3,4 +3,7 @@ SUBDIRS = modules
|
||||
EXTRA_DIST = \
|
||||
FixBundle.cmake.in \
|
||||
config_posix.h.cmake \
|
||||
config_windows.h.cmake
|
||||
config_windows.h.cmake \
|
||||
LibNFCConfig.cmake.in \
|
||||
LibNFCConfigVersion.cmake.in \
|
||||
UseLibNFC.cmake
|
||||
|
||||
5
cmake/UseLibNFC.cmake
Normal file
5
cmake/UseLibNFC.cmake
Normal file
@ -0,0 +1,5 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
add_definitions ( ${LIBNFC_DEFINITIONS} )
|
||||
include_directories ( ${LIBNFC_INCLUDE_DIRS} )
|
||||
link_directories ( ${LIBNFC_LIBRARY_DIRS} )
|
||||
@ -26,9 +26,15 @@ ENDIF(CMAKE_SYSTEM_NAME MATCHES FreeBSD)
|
||||
|
||||
IF(NOT LIBUSB_FOUND)
|
||||
IF(WIN32)
|
||||
FIND_PATH(LIBUSB_INCLUDE_DIRS lusb0_usb.h "$ENV{ProgramFiles}/LibUSB-Win32/include" NO_SYSTEM_ENVIRONMENT_PATH)
|
||||
FIND_LIBRARY(LIBUSB_LIBRARIES NAMES libusb PATHS "$ENV{ProgramFiles}/LibUSB-Win32/lib/gcc")
|
||||
SET(LIBUSB_LIBRARY_DIR "$ENV{ProgramFiles}/LibUSB-Win32/bin/x86/")
|
||||
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)
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
# This CMake script wants to use pcre functionality needed for windows
|
||||
# compilation. However, since PCRE isn't really a default install location
|
||||
# there isn't much to search.
|
||||
#
|
||||
# Operating Systems Supported:
|
||||
# - Windows (requires MinGW)
|
||||
# Tested with Windows XP/Windows 7
|
||||
#
|
||||
# This should work for both 32 bit and 64 bit systems.
|
||||
#
|
||||
# Author: A. Lian <alex.lian@gmail.com>
|
||||
#
|
||||
|
||||
IF(WIN32)
|
||||
IF(NOT PCRE_FOUND)
|
||||
FIND_PATH(PCRE_INCLUDE_DIRS regex.h)
|
||||
FIND_LIBRARY(PCRE_LIBRARIES NAMES PCRE pcre)
|
||||
FIND_PATH(PCRE_BIN_DIRS pcre3.dll)
|
||||
|
||||
IF(PCRE_INCLUDE_DIRS AND PCRE_LIBRARIES AND PCRE_BIN_DIRS)
|
||||
SET(PCRE_FOUND TRUE)
|
||||
ENDIF(PCRE_INCLUDE_DIRS AND PCRE_LIBRARIES AND PCRE_BIN_DIRS)
|
||||
ENDIF(NOT PCRE_FOUND)
|
||||
|
||||
IF(PCRE_FOUND)
|
||||
IF(NOT PCRE_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found PCRE: ${PCRE_LIBRARIES} ${PCRE_INCLUDE_DIRS} ${PCRE_BIN_DIRS}")
|
||||
ENDIF (NOT PCRE_FIND_QUIETLY)
|
||||
ELSE(PCRE_FOUND)
|
||||
IF(PCRE_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find PCRE")
|
||||
ENDIF(PCRE_FIND_REQUIRED)
|
||||
ENDIF(PCRE_FOUND)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG
|
||||
PCRE_LIBRARIES
|
||||
PCRE_INCLUDE_DIRS
|
||||
PCRE_BIN_DIRS
|
||||
)
|
||||
|
||||
ENDIF(WIN32)
|
||||
@ -1,17 +1,24 @@
|
||||
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(WIN32)
|
||||
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)")
|
||||
ELSE(WIN32)
|
||||
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)")
|
||||
ENDIF(WIN32)
|
||||
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")
|
||||
@ -61,4 +68,11 @@ IF(LIBNFC_DRIVER_PN53X_USB)
|
||||
SET(USB_REQUIRED TRUE)
|
||||
ENDIF(LIBNFC_DRIVER_PN53X_USB)
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/drivers)
|
||||
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)
|
||||
|
||||
@ -2,6 +2,5 @@ EXTRA_DIST = \
|
||||
COPYING-CMAKE-SCRIPTS \
|
||||
FindLIBUSB.cmake \
|
||||
FindPCSC.cmake \
|
||||
FindPCRE.cmake \
|
||||
UseDoxygen.cmake \
|
||||
LibnfcDrivers.cmake
|
||||
|
||||
@ -91,8 +91,7 @@ if(DOXYGEN_FOUND AND DOXYFILE_IN)
|
||||
|
||||
configure_file(${DOXYFILE_IN} Doxyfile ESCAPE_QUOTES IMMEDIATE @ONLY)
|
||||
|
||||
get_target_property(DOC_TARGET doc TYPE)
|
||||
if(NOT DOC_TARGET)
|
||||
if(NOT TARGET doc)
|
||||
add_custom_target(doc)
|
||||
endif()
|
||||
|
||||
|
||||
30
configure.ac
30
configure.ac
@ -1,7 +1,7 @@
|
||||
# General init
|
||||
|
||||
# /!\ Don't forget to update 'CMakeLists.txt' too /!\
|
||||
AC_INIT([libnfc],[1.7.1],[nfc-tools@googlegroups.com])
|
||||
AC_INIT([libnfc],[1.8.0],[nfc-tools@googlegroups.com])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
@ -13,7 +13,7 @@ if test x"$GIT_REVISION" != x""; then
|
||||
AC_DEFINE_UNQUOTED([GIT_REVISION], ["$GIT_REVISION"], [GIT revision])
|
||||
fi
|
||||
|
||||
AM_INIT_AUTOMAKE(subdir-objects dist-bzip2 no-dist-gzip)
|
||||
AM_INIT_AUTOMAKE(subdir-objects dist-bzip2 no-dist-gzip foreign)
|
||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||
|
||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
||||
@ -47,6 +47,7 @@ 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([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_DEFINE([_XOPEN_SOURCE], [600], [Enable POSIX extensions if present])])
|
||||
|
||||
@ -125,6 +126,20 @@ 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
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
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
|
||||
|
||||
# Documentation (default: no)
|
||||
AC_ARG_ENABLE([doc],AS_HELP_STRING([--enable-doc],[Enable documentation generation.]),[enable_doc=$enableval],[enable_doc="no"])
|
||||
@ -142,6 +157,14 @@ then
|
||||
fi
|
||||
AM_CONDITIONAL(DOC_ENABLED, [test x"$enable_doc" = xyes])
|
||||
|
||||
# Example build (default: yes)
|
||||
AC_ARG_ENABLE([example],AS_HELP_STRING([--enable-example],[Enable example build.]),[enable_example=$enableval],[enable_example="yes"])
|
||||
|
||||
AC_MSG_CHECKING(for example build)
|
||||
AC_MSG_RESULT($enable_example)
|
||||
|
||||
AM_CONDITIONAL(EXAMPLE_ENABLED, [test x"$enable_example" = xyes])
|
||||
|
||||
# Dependencies
|
||||
PKG_CONFIG_REQUIRES=""
|
||||
|
||||
@ -160,7 +183,10 @@ if test x$ac_cv_with_cutter = xyes -a x$ac_cv_use_cutter = xno; then
|
||||
fi
|
||||
AM_CONDITIONAL([WITH_CUTTER], [test "$ac_cv_use_cutter" != "no"])
|
||||
|
||||
if test x"$enable_example" = "xyes"
|
||||
then
|
||||
AC_CHECK_READLINE
|
||||
fi
|
||||
|
||||
# Help us to write great code ;-)
|
||||
CFLAGS="$CFLAGS -Wall -pedantic -Wextra"
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
EXTRA_DIST = \
|
||||
pn532_via_uart2usb.conf.sample \
|
||||
arygon.conf.sample \
|
||||
pn532_uart_on_rpi.conf.sample
|
||||
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
|
||||
|
||||
22
contrib/libnfc/pn532_uart_on_rpi_3.conf.sample
Normal file
22
contrib/libnfc/pn532_uart_on_rpi_3.conf.sample
Normal file
@ -0,0 +1,22 @@
|
||||
## 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
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
blacklist nfc
|
||||
blacklist pn533
|
||||
blacklist pn533_usb
|
||||
|
||||
@ -11,6 +11,7 @@ ATTRS{idVendor}=="054c", ATTRS{idProduct}=="0193", MODE="0664", GROUP="plugdev"
|
||||
# PN533
|
||||
ATTRS{idVendor}=="04cc", ATTRS{idProduct}=="2533", MODE="0664", GROUP="plugdev"
|
||||
ATTRS{idVendor}=="04e6", ATTRS{idProduct}=="5591", MODE="0664", GROUP="plugdev"
|
||||
ATTRS{idVendor}=="04e6", ATTRS{idProduct}=="5594", MODE="0664", GROUP="plugdev"
|
||||
ATTRS{idVendor}=="1fd3", ATTRS{idProduct}=="0608", MODE="0664", GROUP="plugdev"
|
||||
ATTRS{idVendor}=="054c", ATTRS{idProduct}=="02e1", MODE="0664", GROUP="plugdev"
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
EXTRA_DIST = \
|
||||
42-pn53x.rules
|
||||
93-pn53x.rules
|
||||
|
||||
870
contrib/win32/dirent.h
Normal file
870
contrib/win32/dirent.h
Normal file
@ -0,0 +1,870 @@
|
||||
/*
|
||||
* 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*/
|
||||
|
||||
106
contrib/win32/getopt.c
Normal file
106
contrib/win32/getopt.c
Normal file
@ -0,0 +1,106 @@
|
||||
#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 */
|
||||
}
|
||||
13
contrib/win32/getopt.h
Normal file
13
contrib/win32/getopt.h
Normal file
@ -0,0 +1,13 @@
|
||||
#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
|
||||
@ -123,7 +123,7 @@ 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 bauds.", uiPortSpeed);
|
||||
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:
|
||||
@ -135,7 +135,7 @@ uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
||||
case 460800:
|
||||
break;
|
||||
default:
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200, 230400 or 460800.", uiPortSpeed);
|
||||
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;
|
||||
@ -183,7 +183,7 @@ uart_receive(serial_port sp, uint8_t *pbtRx, const size_t szRx, void *abort_p, i
|
||||
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() mecanism using Cancello()
|
||||
// - 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");
|
||||
|
||||
@ -4,9 +4,10 @@ VERSION 1.7
|
||||
EXPORTS
|
||||
nfc_init
|
||||
nfc_exit
|
||||
nfc_register_driver
|
||||
nfc_open
|
||||
nfc_close
|
||||
nfc_abbort_command
|
||||
nfc_abort_command
|
||||
nfc_list_devices
|
||||
nfc_idle
|
||||
nfc_initiator_init
|
||||
@ -17,7 +18,6 @@ EXPORTS
|
||||
nfc_initiator_select_dep_target
|
||||
nfc_initiator_poll_dep_target
|
||||
nfc_initiator_deselect_target
|
||||
nfc_initiator_poll_targets
|
||||
nfc_initiator_transceive_bytes
|
||||
nfc_initiator_transceive_bits
|
||||
nfc_initiator_transceive_bytes_timed
|
||||
@ -36,13 +36,22 @@ EXPORTS
|
||||
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
|
||||
|
||||
57
contrib/win32/nfc_msvc.def
Normal file
57
contrib/win32/nfc_msvc.def
Normal file
@ -0,0 +1,57 @@
|
||||
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
|
||||
@ -34,21 +34,24 @@
|
||||
// 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)
|
||||
{
|
||||
int exists = GetEnvironmentVariableA(name, NULL, 0);
|
||||
if ((exists && overwrite) || (!exists)) {
|
||||
if (!SetEnvironmentVariableA(name, value)) {
|
||||
// Set errno here correctly
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
char *env = getenv(name);
|
||||
if ((env && overwrite) || (!env)) {
|
||||
char *str[32];
|
||||
strcpy(str, name);
|
||||
strcat(str, "=");
|
||||
strcat(str, value);
|
||||
return putenv(str);
|
||||
}
|
||||
// Exists and overwrite is 0.
|
||||
return -1;
|
||||
}
|
||||
|
||||
void unsetenv(const char *name)
|
||||
{
|
||||
SetEnvironmentVariableA(name, NULL);
|
||||
char *str[32];
|
||||
strcpy(str, name);
|
||||
strcat(str, "=");
|
||||
putenv(str);
|
||||
}
|
||||
|
||||
@ -1,15 +1,9 @@
|
||||
#include "windows.h"
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,0
|
||||
PRODUCTVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG|VS_FF_PRERELEASE
|
||||
#else
|
||||
FILEFLAGS 0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS 0x00040004L
|
||||
FILETYPE @RC_FILE_TYPE@
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
|
||||
@ -48,7 +48,9 @@
|
||||
# define ENOTSUP WSAEOPNOTSUPP
|
||||
# define ECONNABORTED WSAECONNABORTED
|
||||
# else
|
||||
#ifndef _MSC_VER
|
||||
# define snprintf sprintf_s
|
||||
#endif
|
||||
# define strdup _strdup
|
||||
# endif
|
||||
|
||||
|
||||
@ -8,6 +8,10 @@ SET(EXAMPLES-SOURCES
|
||||
nfc-mfsetuid
|
||||
nfc-poll
|
||||
nfc-relay
|
||||
nfc-st25tb
|
||||
pn53x-diagnose
|
||||
pn53x-sam
|
||||
pn53x-tamashell
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libnfc)
|
||||
@ -20,9 +24,15 @@ FOREACH(source ${EXAMPLES-SOURCES})
|
||||
SET(RC_COMMENT "${PACKAGE_NAME} example")
|
||||
SET(RC_INTERNAL_NAME ${source})
|
||||
SET(RC_ORIGINAL_NAME ${source}.exe)
|
||||
SET(RC_FILE_TYPE VFT_APP)
|
||||
# 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})
|
||||
|
||||
@ -10,6 +10,7 @@ bin_PROGRAMS = \
|
||||
nfc-mfsetuid \
|
||||
nfc-poll \
|
||||
nfc-relay \
|
||||
nfc-st25tb \
|
||||
pn53x-diagnose \
|
||||
pn53x-sam
|
||||
|
||||
@ -63,6 +64,9 @@ 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_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
||||
$(top_builddir)/utils/libnfcutils.la
|
||||
@ -74,6 +78,7 @@ pn53x_sam_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
||||
pn53x_tamashell_SOURCES = pn53x-tamashell.c
|
||||
pn53x_tamashell_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
||||
$(top_builddir)/utils/libnfcutils.la
|
||||
pn53x_tamashell_CFLAGS = @READLINE_INCLUDES@ -I$(top_srcdir)
|
||||
pn53x_tamashell_LDFLAGS = @READLINE_LIBS@
|
||||
|
||||
quick_start_example1_SOURCES = doc/quick_start_example1.c
|
||||
|
||||
@ -23,7 +23,7 @@ Please report any bugs on the
|
||||
.B libnfc
|
||||
issue tracker at:
|
||||
.br
|
||||
.BR http://code.google.com/p/libnfc/issues
|
||||
.BR https://github.com/nfc-tools/libnfc/issues
|
||||
.SH LICENCE
|
||||
.B libnfc
|
||||
is licensed under the GNU Lesser General Public License (LGPL), version 3.
|
||||
|
||||
@ -18,7 +18,7 @@ Please report any bugs on the
|
||||
.B libnfc
|
||||
issue tracker at:
|
||||
.br
|
||||
.BR http://code.google.com/p/libnfc/issues
|
||||
.BR https://github.com/nfc-tools/libnfc/issues
|
||||
.SH LICENCE
|
||||
.B libnfc
|
||||
is licensed under the GNU Lesser General Public License (LGPL), version 3.
|
||||
|
||||
@ -18,7 +18,7 @@ Please report any bugs on the
|
||||
.B libnfc
|
||||
issue tracker at:
|
||||
.br
|
||||
.BR http://code.google.com/p/libnfc/issues
|
||||
.BR https://github.com/nfc-tools/libnfc/issues
|
||||
.SH LICENCE
|
||||
.B libnfc
|
||||
is licensed under the GNU Lesser General Public License (LGPL), version 3.
|
||||
|
||||
@ -35,7 +35,7 @@ bug, this problem is due to ACR122's internal MCU in front of NFC chip (PN532).
|
||||
Please report any bugs on the
|
||||
.Em libnfc
|
||||
issue tracker at:
|
||||
.Em http://code.google.com/p/libnfc/issues
|
||||
.Em https://github.com/nfc-tools/libnfc/issues
|
||||
.Sh LICENCE
|
||||
.Em libnfc
|
||||
is licensed under the GNU Lesser General Public License (LGPL), version 3.
|
||||
|
||||
@ -39,7 +39,7 @@ Please report any bugs on the
|
||||
.B libnfc
|
||||
issue tracker at:
|
||||
.br
|
||||
.BR http://code.google.com/p/libnfc/issues
|
||||
.BR https://github.com/nfc-tools/libnfc/issues
|
||||
.SH LICENCE
|
||||
.B libnfc
|
||||
is licensed under the GNU Lesser General Public License (LGPL), version 3.
|
||||
|
||||
@ -266,9 +266,9 @@ main(int argc, char *argv[])
|
||||
},
|
||||
.nti = {
|
||||
.nai = {
|
||||
abtAtqa = { 0x03, 0x44 },
|
||||
abtUid = { 0x08, 0xab, 0xcd, 0xef },
|
||||
btSak = 0x20,
|
||||
.abtAtqa = { 0x03, 0x44 },
|
||||
.abtUid = { 0x08, 0xab, 0xcd, 0xef },
|
||||
.btSak = 0x20,
|
||||
.szUidLen = 4,
|
||||
.abtAts = { 0x75, 0x77, 0x81, 0x02, 0x80 },
|
||||
.szAtsLen = 5,
|
||||
|
||||
@ -14,7 +14,7 @@ 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
|
||||
transmission of raw frames, and the desired UID can be optionally specified.
|
||||
|
||||
This makes it a serious thread for security systems that rely only on the
|
||||
This makes it a serious threat for security systems that rely only on the
|
||||
uniqueness of the UID.
|
||||
|
||||
Unfortunately, this example can't directly start in fully customisable
|
||||
@ -54,7 +54,7 @@ Please report any bugs on the
|
||||
.B libnfc
|
||||
issue tracker at:
|
||||
.br
|
||||
.BR http://code.google.com/p/libnfc/issues
|
||||
.BR https://github.com/nfc-tools/libnfc/issues
|
||||
.SH LICENCE
|
||||
.B libnfc
|
||||
is licensed under the GNU Lesser General Public License (LGPL), version 3.
|
||||
|
||||
@ -79,7 +79,10 @@ intr_hdlr(int sig)
|
||||
if (pnd != NULL) {
|
||||
printf("\nAborting current command...\n");
|
||||
nfc_abort_command(pnd);
|
||||
nfc_close(pnd);
|
||||
}
|
||||
nfc_exit(context);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -237,7 +240,4 @@ main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
}
|
||||
nfc_close(pnd);
|
||||
nfc_exit(context);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ Please report any bugs on the
|
||||
.B libnfc
|
||||
issue tracker at:
|
||||
.br
|
||||
.BR http://code.google.com/p/libnfc/issues
|
||||
.BR https://github.com/nfc-tools/libnfc/issues
|
||||
.SH LICENCE
|
||||
.B libnfc
|
||||
is licensed under the GNU Lesser General Public License (LGPL), version 3.
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
* See AUTHORS file for a more comprehensive list of contributors.
|
||||
* Additional contributors of this file:
|
||||
* Copyright (C) 2011 Adam Laurie
|
||||
* Copyright (C) 2014 Dario Carluccio
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -140,12 +141,13 @@ transmit_bytes(const uint8_t *pbtTx, const size_t szTx)
|
||||
static void
|
||||
print_usage(char *argv[])
|
||||
{
|
||||
printf("Usage: %s [OPTIONS] [UID]\n", argv[0]);
|
||||
printf("Usage: %s [OPTIONS] [UID|BLOCK0]\n", argv[0]);
|
||||
printf("Options:\n");
|
||||
printf("\t-h\tHelp. Print this message.\n");
|
||||
printf("\t-f\tFormat. Delete all data (set to 0xFF) and reset ACLs to default.\n");
|
||||
printf("\t-q\tQuiet mode. Suppress output of READER and CARD data (improves timing).\n");
|
||||
printf("\n\tSpecify UID (4 HEX bytes) to set UID, or leave blank for default '01234567'.\n");
|
||||
printf("\n\tSpecify BLOCK0 (16 HEX bytes) to set content of Block0. CRC (Byte 4) is recalculated an overwritten'.\n");
|
||||
printf("\tThis utility can be used to recover cards that have been damaged by writing bad\n");
|
||||
printf("\tdata (e.g. wrong BCC), thus making them non-selectable by most tools/readers.\n");
|
||||
printf("\n\t*** Note: this utility only works with special Mifare 1K cards (Chinese clones).\n\n");
|
||||
@ -177,6 +179,14 @@ main(int argc, char *argv[])
|
||||
}
|
||||
abtData[4] = abtData[0] ^ abtData[1] ^ abtData[2] ^ abtData[3];
|
||||
iso14443a_crc_append(abtData, 16);
|
||||
} else if (strlen(argv[arg]) == 32) {
|
||||
for (i = 0 ; i < 16 ; ++i) {
|
||||
memcpy(tmp, argv[arg] + i * 2, 2);
|
||||
sscanf(tmp, "%02x", &c);
|
||||
abtData[i] = (char) c;
|
||||
}
|
||||
abtData[4] = abtData[0] ^ abtData[1] ^ abtData[2] ^ abtData[3];
|
||||
iso14443a_crc_append(abtData, 16);
|
||||
} else {
|
||||
ERR("%s is not supported option.", argv[arg]);
|
||||
print_usage(argv);
|
||||
@ -355,13 +365,23 @@ main(int argc, char *argv[])
|
||||
// now reset UID
|
||||
iso14443a_crc_append(abtHalt, 2);
|
||||
transmit_bytes(abtHalt, 4);
|
||||
transmit_bits(abtUnlock1, 7);
|
||||
if (format) {
|
||||
transmit_bytes(abtWipe, 1);
|
||||
transmit_bytes(abtHalt, 4);
|
||||
transmit_bits(abtUnlock1, 7);
|
||||
|
||||
if (!transmit_bits(abtUnlock1, 7)) {
|
||||
printf("Warning: Unlock command [1/2]: failed / not acknowledged.\n");
|
||||
} else {
|
||||
if (format) {
|
||||
transmit_bytes(abtWipe, 1);
|
||||
transmit_bytes(abtHalt, 4);
|
||||
transmit_bits(abtUnlock1, 7);
|
||||
}
|
||||
|
||||
if (transmit_bytes(abtUnlock2, 1)) {
|
||||
printf("Card unlocked\n");
|
||||
} else {
|
||||
printf("Warning: Unlock command [2/2]: failed / not acknowledged.\n");
|
||||
}
|
||||
}
|
||||
transmit_bytes(abtUnlock2, 1);
|
||||
|
||||
transmit_bytes(abtWrite, 4);
|
||||
transmit_bytes(abtData, 18);
|
||||
if (format) {
|
||||
|
||||
@ -42,7 +42,7 @@ Please report any bugs on the
|
||||
.B libnfc
|
||||
issue tracker at:
|
||||
.br
|
||||
.BR http://code.google.com/p/libnfc/issues
|
||||
.BR https://github.com/nfc-tools/libnfc/issues
|
||||
.SH LICENCE
|
||||
.B libnfc
|
||||
is licensed under the GNU Lesser General Public License (LGPL), version 3.
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||
* See AUTHORS file for a more comprehensive list of contributors.
|
||||
* Additional contributors of this file:
|
||||
* Copyright (C) 2020 Adam Laurie
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -101,14 +102,15 @@ main(int argc, const char *argv[])
|
||||
|
||||
const uint8_t uiPollNr = 20;
|
||||
const uint8_t uiPeriod = 2;
|
||||
const nfc_modulation nmModulations[5] = {
|
||||
const nfc_modulation nmModulations[6] = {
|
||||
{ .nmt = NMT_ISO14443A, .nbr = NBR_106 },
|
||||
{ .nmt = NMT_ISO14443B, .nbr = NBR_106 },
|
||||
{ .nmt = NMT_FELICA, .nbr = NBR_212 },
|
||||
{ .nmt = NMT_FELICA, .nbr = NBR_424 },
|
||||
{ .nmt = NMT_JEWEL, .nbr = NBR_106 },
|
||||
{ .nmt = NMT_ISO14443BICLASS, .nbr = NBR_106 },
|
||||
};
|
||||
const size_t szModulations = 5;
|
||||
const size_t szModulations = 6;
|
||||
|
||||
nfc_target nt;
|
||||
int res = 0;
|
||||
@ -145,15 +147,15 @@ main(int argc, const char *argv[])
|
||||
|
||||
if (res > 0) {
|
||||
print_nfc_target(&nt, verbose);
|
||||
printf("Waiting for card removing...");
|
||||
fflush(stdout);
|
||||
while (0 == nfc_initiator_target_is_present(pnd, NULL)) {}
|
||||
nfc_perror(pnd, "nfc_initiator_target_is_present");
|
||||
printf("done.\n");
|
||||
} else {
|
||||
printf("No target found.\n");
|
||||
}
|
||||
|
||||
printf("Waiting for card removing...");
|
||||
while (0 == nfc_initiator_target_is_present(pnd, NULL)) {}
|
||||
nfc_perror(pnd, "nfc_initiator_target_is_present");
|
||||
printf("done.\n");
|
||||
|
||||
nfc_close(pnd);
|
||||
nfc_exit(context);
|
||||
exit(EXIT_SUCCESS);
|
||||
|
||||
@ -22,7 +22,7 @@ Please report any bugs on the
|
||||
.B libnfc
|
||||
issue tracker at:
|
||||
.br
|
||||
.BR http://code.google.com/p/libnfc/issues
|
||||
.BR https://github.com/nfc-tools/libnfc/issues
|
||||
.SH LICENCE
|
||||
.B libnfc
|
||||
is licensed under the GNU Lesser General Public License (LGPL), version 3.
|
||||
|
||||
600
examples/nfc-st25tb.c
Normal file
600
examples/nfc-st25tb.c
Normal file
@ -0,0 +1,600 @@
|
||||
/*-
|
||||
* 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-st25tb.c
|
||||
* @brief Tool to operate on ISO-14443-B ST25TB* and legacy SR* cards
|
||||
*/
|
||||
|
||||
/* Benjamin DELPY `gentilkiwi`
|
||||
* https://blog.gentilkiwi.com
|
||||
* benjamin@gentilkiwi.com
|
||||
* Licence : https://creativecommons.org/licenses/by/4.0/
|
||||
* Rely on : libnfc - https://github.com/nfc-tools/libnfc
|
||||
*
|
||||
* $ gcc -Wall -lnfc -o nfc-st25tb nfc-st25tb.c
|
||||
* $ ./nfc-st25tb -h
|
||||
*
|
||||
* Tested with
|
||||
* - ST25TB512-AC - (BE/Brussels/STIB ; AliExpress ones)
|
||||
* - ST25TB512-AT - (FR/Lille/Ilevia ; FR/Reims/Citura ; FR/Dijon/Divia ; FR/Strasbourg/CTS)
|
||||
* - SRT512 - legacy - (FR/Bordeaux/TBM)
|
||||
* - SRI512 - legacy - (anonymous vending machine)
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <nfc/nfc.h>
|
||||
|
||||
#if defined(WIN32) /* mingw compiler */
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
#define ST25TB_SR_BLOCK_MAX_SIZE ((uint8_t) 4) // for static arrays
|
||||
typedef void(*get_info_specific) (uint8_t * systemArea);
|
||||
|
||||
typedef struct _st_data {
|
||||
uint8_t chipId;
|
||||
bool bIsLegacy;
|
||||
const char *szName;
|
||||
const char *szDatasheetUrl;
|
||||
uint8_t blockSize;
|
||||
uint8_t nbNormalBlock;
|
||||
uint8_t bnSystem;
|
||||
get_info_specific pfnGetInfo;
|
||||
} st_data;
|
||||
|
||||
bool get_block_at(nfc_device *pnd, uint8_t block, uint8_t *data, uint8_t cbData, bool bPrintIt);
|
||||
bool set_block_at(nfc_device *pnd, uint8_t block, uint8_t *data, uint8_t cbData, bool bPrintIt);
|
||||
bool set_block_at_confirmed(nfc_device *pnd, uint8_t block, uint8_t *data, uint8_t cbData, bool bPrintIt);
|
||||
const st_data * get_info(const nfc_target *pnt, bool bPrintIt);
|
||||
void display_system_info(nfc_device *pnd, const st_data * stdata);
|
||||
void print_hex(const uint8_t *pbtData, const size_t szBytes);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
nfc_context *context = NULL;
|
||||
nfc_device *pnd = NULL;
|
||||
nfc_target nt = {0};
|
||||
nfc_modulation nm = {NMT_ISO14443B2SR, NBR_106};
|
||||
const st_data * stcurrent;
|
||||
int opt, res;
|
||||
bool bIsBlock = false, bIsRead = false, bIsWrite = false, bIsBadCli = false;
|
||||
uint8_t i, blockNumber = 0, data[ST25TB_SR_BLOCK_MAX_SIZE] = {0xff, 0xff, 0xff, 0xff}; // just in case...
|
||||
size_t cbData = 0;
|
||||
|
||||
while(!bIsBadCli && ((opt = getopt(argc, argv, ":hib:rw:")) != -1))
|
||||
{
|
||||
switch(opt)
|
||||
{
|
||||
case 'i':
|
||||
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
if(optarg)
|
||||
{
|
||||
bIsBlock = true;
|
||||
blockNumber = strtoul(optarg, NULL, 0);
|
||||
}
|
||||
else bIsBadCli = true;
|
||||
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
bIsRead = true;
|
||||
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
if(optarg)
|
||||
{
|
||||
cbData = strlen(optarg);
|
||||
if((cbData == (2*2)) || ((cbData == (4*2))))
|
||||
{
|
||||
cbData >>= 1;
|
||||
if(cbData == 2) // sr176
|
||||
{
|
||||
res = sscanf(optarg, "%02hhx%02hhx", data, data + 1);
|
||||
}
|
||||
else // all others
|
||||
{
|
||||
res = sscanf(optarg, "%02hhx%02hhx%02hhx%02hhx", data, data + 1, data + 2, data + 3);
|
||||
}
|
||||
|
||||
if(res == (int) cbData)
|
||||
{
|
||||
bIsWrite = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!bIsWrite)
|
||||
{
|
||||
bIsBadCli = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default: // includes -h
|
||||
bIsBadCli = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(!bIsBadCli)
|
||||
{
|
||||
if(bIsBlock && (bIsRead || bIsWrite))
|
||||
{
|
||||
if(bIsRead && bIsWrite)
|
||||
{
|
||||
printf("|mode : read then write\n");
|
||||
}
|
||||
else if(bIsRead)
|
||||
{
|
||||
printf("|mode : read\n");
|
||||
}
|
||||
else if(bIsWrite)
|
||||
{
|
||||
printf("|mode : write\n");
|
||||
}
|
||||
|
||||
printf("|blk num: 0x%02hhx\n", blockNumber);
|
||||
if(bIsWrite)
|
||||
{
|
||||
printf("|data : ");
|
||||
print_hex(data, cbData);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
else if(!bIsRead && !bIsWrite && !bIsBlock)
|
||||
{
|
||||
printf("|mode : info\n");
|
||||
}
|
||||
else bIsBadCli = true;
|
||||
}
|
||||
|
||||
if(!bIsBadCli)
|
||||
{
|
||||
nfc_init(&context);
|
||||
if(context)
|
||||
{
|
||||
pnd = nfc_open(context, NULL);
|
||||
if(pnd)
|
||||
{
|
||||
res = nfc_initiator_init(pnd);
|
||||
if(res == NFC_SUCCESS)
|
||||
{
|
||||
printf("Reader : %s - via %s\n ...wait for card...\n", nfc_device_get_name(pnd), nfc_device_get_connstring(pnd));
|
||||
|
||||
if (nfc_initiator_select_passive_target(pnd, nm, NULL, 0, &nt) > 0)
|
||||
{
|
||||
stcurrent = get_info(&nt, true);
|
||||
if(stcurrent)
|
||||
{
|
||||
printf("\n");
|
||||
|
||||
if(bIsBlock && (bIsRead || bIsWrite))
|
||||
{
|
||||
if(bIsRead)
|
||||
{
|
||||
get_block_at(pnd, blockNumber, NULL, 0, true);
|
||||
}
|
||||
|
||||
if(bIsWrite)
|
||||
{
|
||||
set_block_at_confirmed(pnd, blockNumber, data, cbData, true);
|
||||
}
|
||||
}
|
||||
else if(!bIsRead && !bIsWrite && !bIsBlock)
|
||||
{
|
||||
for(i = 0; i < stcurrent->nbNormalBlock; i++)
|
||||
{
|
||||
get_block_at(pnd, i, NULL, 0, true);
|
||||
}
|
||||
display_system_info(pnd, stcurrent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else printf("ERROR - nfc_initiator_init: %i\n", res);
|
||||
|
||||
nfc_close(pnd);
|
||||
}
|
||||
else printf("ERROR - nfc_open\n");
|
||||
|
||||
nfc_exit(context);
|
||||
}
|
||||
else printf("ERROR - nfc_init\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(
|
||||
"Usage:\n"
|
||||
" %s [-i]\n"
|
||||
" %s -b N -r\n"
|
||||
" %s -b N [-r] -w ABCD[EF01]\n %s -h\n"
|
||||
"Options:\n"
|
||||
" -i (default) information mode - will try to dump the tag content and display informations\n"
|
||||
" -b N specify block number to operate on (tag dependent), needed for read (-r) and write (-w) modes\n"
|
||||
" -r read mode - will try to read block (specified with -b N parameter)\n"
|
||||
" -w ABCD[EF01] write mode - will try to write specicied data (2 or 4 bytes depending on tag) to block (specified with -b N parameter)\n"
|
||||
" -h this help\n"
|
||||
"Examples:\n"
|
||||
" %s -i\n"
|
||||
" Display all tag informations\n"
|
||||
" %s -b 0x0e -r\n"
|
||||
" Read block 0x0e (14) of the tag\n"
|
||||
" %s -b 0x0d -w 0123abcd\n"
|
||||
" Write block 0x0d (13) of the tag with hexadecimal value '01 23 ab cd'\n"
|
||||
" %s -b 0x0c -r -w 0123abcd\n"
|
||||
" Read, then write block 0x0c (12) of the tag with hexadecimal value '01 23 ab cd'\n"
|
||||
"Warnings:\n"
|
||||
" Be careful with: system area, counters & otp, bytes order.\n"
|
||||
, argv[0], argv[0], argv[0], argv[0], argv[0], argv[0], argv[0], argv[0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool get_block_at(nfc_device *pnd, uint8_t block, uint8_t *data, uint8_t cbData, bool bPrintIt)
|
||||
{
|
||||
bool bRet = false;
|
||||
uint8_t tx[2] = {0x08, block}, rx[ST25TB_SR_BLOCK_MAX_SIZE]; // 4 is the maximum, SR176 (only 2) will fit
|
||||
int res;
|
||||
|
||||
res = nfc_initiator_transceive_bytes(pnd, tx, sizeof(tx), rx, sizeof(rx), 0);
|
||||
if((res == 2) || (res == 4))
|
||||
{
|
||||
if(data)
|
||||
{
|
||||
if(cbData == res)
|
||||
{
|
||||
memcpy(data, rx, res);
|
||||
bRet = true;
|
||||
}
|
||||
else printf("ERROR - We got %i bytes for a %hhu buffer size?\n", res, cbData);
|
||||
}
|
||||
else bRet = true;
|
||||
|
||||
if(bPrintIt)
|
||||
{
|
||||
printf("[0x%02hhx] ", block);
|
||||
print_hex(rx, res);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
else if(res > 0)
|
||||
{
|
||||
printf("ERROR - We got %i bytes?\n", res);
|
||||
}
|
||||
else printf("ERROR - nfc_initiator_transceive_bytes(get): %i\n", res);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool set_block_at(nfc_device *pnd, uint8_t block, uint8_t *data, uint8_t cbData, bool bPrintIt)
|
||||
{
|
||||
bool bRet = false;
|
||||
uint8_t tx[2 + ST25TB_SR_BLOCK_MAX_SIZE] = {0x09, block}; // 4 is the maximum, SR176 (only 2) will fit
|
||||
int res;
|
||||
|
||||
if(cbData <= ST25TB_SR_BLOCK_MAX_SIZE)
|
||||
{
|
||||
memcpy(tx + 2, data, cbData);
|
||||
|
||||
if(bPrintIt)
|
||||
{
|
||||
printf(">0x%02hhx> ", block);
|
||||
print_hex(data, cbData);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
res = nfc_initiator_transceive_bytes(pnd, tx, 2 + cbData, NULL, 0, 0);
|
||||
if(res == NFC_ERFTRANS) // ? :')
|
||||
{
|
||||
bRet = true;
|
||||
}
|
||||
else printf("ERROR - nfc_initiator_transceive_bytes(set): %i\n", res);
|
||||
}
|
||||
else printf("ERROR - Wanted to write %hhu bytes, but maximum is %hhu\n", cbData, ST25TB_SR_BLOCK_MAX_SIZE);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool set_block_at_confirmed(nfc_device *pnd, uint8_t block, uint8_t *data, uint8_t cbData, bool bPrintIt)
|
||||
{
|
||||
bool bRet = false;
|
||||
uint8_t buffer[ST25TB_SR_BLOCK_MAX_SIZE]; // maximum size will be checked in set_block_at
|
||||
|
||||
if(set_block_at(pnd, block, data, cbData, bPrintIt))
|
||||
{
|
||||
if(get_block_at(pnd, block, buffer, cbData, bPrintIt))
|
||||
{
|
||||
if(memcmp(data, buffer, cbData) == 0)
|
||||
{
|
||||
bRet = true;
|
||||
}
|
||||
else if(bPrintIt)
|
||||
{
|
||||
printf("WARNING - not same value readed after write\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
void get_info_st25tb512(uint8_t * systemArea)
|
||||
{
|
||||
uint8_t b, i;
|
||||
|
||||
b = ((*(uint32_t *) systemArea) >> 15) & 1;
|
||||
|
||||
printf(" | ST reserved : ");
|
||||
for(i = 0; i < 15; i++)
|
||||
{
|
||||
printf("%hhu", (uint8_t) (((*(uint32_t *) systemArea) >> i) & 1));
|
||||
}
|
||||
printf("\n | b15 : %hhu - %sOTP (?)\n | OTP_Lock_Reg : ", b, b ? "not " : "");
|
||||
for(i = 16; i < 32; i++)
|
||||
{
|
||||
printf("%hhu", (uint8_t) (((*(uint32_t *) systemArea) >> i) & 1));
|
||||
}
|
||||
printf("\n");
|
||||
for(i = 16; i < 32; i++)
|
||||
{
|
||||
if(!(((*(uint32_t *) systemArea) >> i) & 1))
|
||||
{
|
||||
printf(" block 0x%02hhx is write protected\n", ((uint8_t) (i - 16)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void get_info_st25tb2k_4k(uint8_t * systemArea)
|
||||
{
|
||||
uint8_t b, i;
|
||||
|
||||
b = ((*(uint32_t *) systemArea) >> 15) & 1;
|
||||
|
||||
printf(" | ST reserved : ");
|
||||
for(i = 0; i < 15; i++)
|
||||
{
|
||||
printf("%hhu", (uint8_t) (((*(uint32_t *) systemArea) >> i) & 1));
|
||||
}
|
||||
printf("\n | b15 : %hhu - %sOTP (?)\n | OTP_Lock_RegU: ", b, b ? "not " : "");
|
||||
for(i = 16; i < 24; i++)
|
||||
{
|
||||
printf("%hhu", (uint8_t) (((*(uint32_t *) systemArea) >> i) & 1));
|
||||
}
|
||||
printf("\n | OTP_Lock_Reg : ");
|
||||
for(i = 24; i < 32; i++)
|
||||
{
|
||||
printf("%hhu", (uint8_t) (((*(uint32_t *) systemArea) >> i) & 1));
|
||||
}
|
||||
printf("\n");
|
||||
if(!(((*(uint32_t *) systemArea) >> 24) & 1))
|
||||
{
|
||||
printf(" blocks 0x07 and 0x08 are write protected\n");
|
||||
}
|
||||
for(i = 25; i < 32; i++)
|
||||
{
|
||||
if(!(((*(uint32_t *) systemArea) >> i) & 1))
|
||||
{
|
||||
printf(" block 0x%02hhx is write protected\n", ((uint8_t) (i - 16)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void get_info_sr176_legacy(uint8_t * systemArea)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
printf(" | Fixed Chip_ID: 0x%1x\n | ST reserved : ", systemArea[0] & 0x0f);
|
||||
for(i = 4; i < 8; i++)
|
||||
{
|
||||
printf("%hhu", (uint8_t) (((*(uint16_t *) systemArea) >> i) & 1));
|
||||
}
|
||||
printf("\n | OTP_Lock_Reg : ");
|
||||
for(i = 8; i < 16; i++)
|
||||
{
|
||||
printf("%hhu", (uint8_t) (((*(uint16_t *) systemArea) >> i) & 1));
|
||||
}
|
||||
printf("\n");
|
||||
for(i = 8; i < 16; i++)
|
||||
{
|
||||
if(((*(uint16_t *) systemArea) >> i) & 1)
|
||||
{
|
||||
printf(" blocks 0x%02hhx and 0x%02hhx are write protected\n", (uint8_t) ((i - 8) * 2), (uint8_t) (((i - 8) * 2) + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void get_info_sri_srt_512_legacy(uint8_t * systemArea)
|
||||
{
|
||||
uint8_t b, i;
|
||||
|
||||
b = ((*(uint32_t *) systemArea) >> 15) & 1;
|
||||
|
||||
printf(" | Fixed Chip_ID: 0x%02hhx\n | ST reserved : ", systemArea[0]);
|
||||
for(i = 8; i < 15; i++)
|
||||
{
|
||||
printf("%hhu", (uint8_t) (((*(uint32_t *) systemArea) >> i) & 1));
|
||||
}
|
||||
printf("\n | b15 : %hhu - %sOTP (?)\n | OTP_Lock_Reg : ", b, b ? "not " : "");
|
||||
for(i = 16; i < 32; i++)
|
||||
{
|
||||
printf("%hhu", (uint8_t) (((*(uint32_t *) systemArea) >> i) & 1));
|
||||
}
|
||||
printf("\n");
|
||||
for(i = 16; i < 32; i++)
|
||||
{
|
||||
if(!(((*(uint32_t *) systemArea) >> i) & 1))
|
||||
{
|
||||
printf(" block 0x%02hhx is write protected\n", (uint8_t) (i - 16));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void get_info_sri2k_4k_srix4k_srix512_legacy(uint8_t * systemArea)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
printf(" | Fixed Chip_ID: 0x%02hhx\n | ST reserved : ", systemArea[0]);
|
||||
for(i = 8; i < 24; i++)
|
||||
{
|
||||
printf("%hhu", (uint8_t) (((*(uint32_t *) systemArea) >> i) & 1));
|
||||
}
|
||||
printf("\n | OTP_Lock_Reg : ");
|
||||
for(i = 24; i < 32; i++)
|
||||
{
|
||||
printf("%hhu", (uint8_t) (((*(uint32_t *) systemArea) >> i) & 1));
|
||||
}
|
||||
printf("\n");
|
||||
if(!(((*(uint32_t *) systemArea) >> 24) & 1))
|
||||
{
|
||||
printf(" blocks 0x07 and 0x08 are write protected\n");
|
||||
}
|
||||
for(i = 25; i < 32; i++)
|
||||
{
|
||||
if(!(((*(uint32_t *) systemArea) >> i) & 1))
|
||||
{
|
||||
printf(" block 0x%02hhx is write protected\n", (uint8_t) (i - 16));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const st_data STRefs[] = {
|
||||
{0x1b, false, "ST25TB512-AC", "https://www.st.com/resource/en/datasheet/st25tb512-ac.pdf", 4, 16, 255, get_info_st25tb512},
|
||||
{0x33, false, "ST25TB512-AT", "https://www.st.com/resource/en/datasheet/st25tb512-at.pdf", 4, 16, 255, get_info_st25tb512},
|
||||
{0x3f, false, "ST25TB02K", "https://www.st.com/resource/en/datasheet/st25tb02k.pdf", 4, 64, 255, get_info_st25tb2k_4k},
|
||||
{0x1f, false, "ST25TB04K", "https://www.st.com/resource/en/datasheet/st25tb04k.pdf", 4, 128, 255, get_info_st25tb2k_4k},
|
||||
};
|
||||
const st_data STRefs_legacy[] = {
|
||||
{ 0, true, "SRI4K(s)", NULL, 4, 128, 255, NULL},
|
||||
{ 2, true, "SR176", "https://www.st.com/resource/en/datasheet/sr176.pdf", 2, 15, 15, get_info_sr176_legacy},
|
||||
{ 3, true, "SRIX4K", NULL, 4, 128, 255, get_info_sri2k_4k_srix4k_srix512_legacy},
|
||||
{ 4, true, "SRIX512", "https://www.st.com/resource/en/datasheet/srix512.pdf", 4, 16, 255, get_info_sri2k_4k_srix4k_srix512_legacy},
|
||||
{ 6, true, "SRI512", "https://www.st.com/resource/en/datasheet/sri512.pdf", 4, 16, 255, get_info_sri_srt_512_legacy},
|
||||
{ 7, true, "SRI4K", "https://www.st.com/resource/en/datasheet/sri4k.pdf", 4, 128, 255, get_info_sri2k_4k_srix4k_srix512_legacy},
|
||||
{12, true, "SRT512", "https://www.st.com/resource/en/datasheet/srt512.pdf", 4, 16, 255, get_info_sri_srt_512_legacy},
|
||||
{15, true, "SRI2K", "https://www.st.com/resource/en/datasheet/sri2k.pdf", 4, 64, 255, get_info_sri2k_4k_srix4k_srix512_legacy},
|
||||
};
|
||||
|
||||
const st_data * get_info(const nfc_target *pnt, bool bPrintIt)
|
||||
{
|
||||
const st_data *currentData = NULL;
|
||||
const uint8_t *p;
|
||||
uint8_t chipId, i;
|
||||
|
||||
if(pnt->nm.nmt == NMT_ISO14443B2SR)
|
||||
{
|
||||
printf("Target : %s (%s)\nUID : ", str_nfc_modulation_type(pnt->nm.nmt), str_nfc_baud_rate(pnt->nm.nbr));
|
||||
print_hex(pnt->nti.nsi.abtUID, sizeof(pnt->nti.nsi.abtUID));
|
||||
printf("\n");
|
||||
|
||||
p = pnt->nti.nsi.abtUID;
|
||||
if(p[7] == 0xd0) // ST25TB* / SR*
|
||||
{
|
||||
chipId = p[5];
|
||||
printf("Manuf : 0x%02hhx - %s\n", p[6], (p[6] == 0x02) ? "STMicroelectronics" : "other");
|
||||
|
||||
for(i = 0; i < (sizeof(STRefs) / sizeof(STRefs[0])); i++)
|
||||
{
|
||||
if(chipId == STRefs[i].chipId)
|
||||
{
|
||||
currentData = &STRefs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!currentData)
|
||||
{
|
||||
chipId >>= 2;
|
||||
for(i = 0; i < (sizeof(STRefs_legacy) / sizeof(STRefs_legacy[0])); i++)
|
||||
{
|
||||
if(chipId == STRefs_legacy[i].chipId)
|
||||
{
|
||||
currentData = &STRefs_legacy[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(bPrintIt && currentData)
|
||||
{
|
||||
printf("ChipId : 0x%02hhx - %s%s\nSerial : 0x", currentData->chipId, currentData->szName, currentData->bIsLegacy ? " (legacy)" : "");
|
||||
if(currentData->bIsLegacy)
|
||||
{
|
||||
printf("%1hhx", (uint8_t) (p[5] & 0x03));
|
||||
}
|
||||
printf("%02hhx%02hhx%02hhx%02hhx%02hhx\n|blk sz : %hhu bits\n|nb blks: %hhu\n|sys idx: %hhu\n", p[4], p[3], p[2], p[1], p[0], (uint8_t) (currentData->blockSize * 8), currentData->nbNormalBlock, currentData->bnSystem);
|
||||
}
|
||||
}
|
||||
else printf("WARNI - Last byte of UID isn\'t 0xd0, but 0x%02hhx (not ST25TB / SR series?)\n", p[7]);
|
||||
}
|
||||
else printf("ERROR - not a NMT_ISO14443B2SR ?\n");
|
||||
|
||||
return currentData;
|
||||
}
|
||||
|
||||
void display_system_info(nfc_device *pnd, const st_data * stdata)
|
||||
{
|
||||
uint8_t systemArea[ST25TB_SR_BLOCK_MAX_SIZE];
|
||||
|
||||
if(get_block_at(pnd, stdata->bnSystem, systemArea, stdata->blockSize, true))
|
||||
{
|
||||
if(stdata->pfnGetInfo)
|
||||
{
|
||||
stdata->pfnGetInfo(systemArea);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_hex(const uint8_t *pbtData, const size_t szBytes)
|
||||
{
|
||||
size_t szPos;
|
||||
for (szPos = 0; szPos < szBytes; szPos++)
|
||||
{
|
||||
printf("%02hhx ", pbtData[szPos]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ Please report any bugs on the
|
||||
.B libnfc
|
||||
issue tracker at:
|
||||
.br
|
||||
.BR http://code.google.com/p/libnfc/issues
|
||||
.BR https://github.com/nfc-tools/libnfc/issues
|
||||
.SH LICENCE
|
||||
.B libnfc
|
||||
is licensed under the GNU Lesser General Public License (LGPL), version 3.
|
||||
|
||||
@ -19,7 +19,7 @@ Please report any bugs on the
|
||||
.B libnfc
|
||||
issue tracker at:
|
||||
.br
|
||||
.BR http://code.google.com/p/libnfc/issues
|
||||
.BR https://github.com/nfc-tools/libnfc/issues
|
||||
.SH LICENCE
|
||||
.B libnfc
|
||||
is licensed under the GNU Lesser General Public License (LGPL), version 3.
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
#DEBUG='//;'
|
||||
|
||||
cat << EOF | \
|
||||
pn53x-tamashell |\
|
||||
awk '\
|
||||
awk $DEBUG'\
|
||||
/^> #.*:/{
|
||||
sub(/^> #/,"")
|
||||
n=$0
|
||||
@ -21,27 +23,33 @@ cat << EOF | \
|
||||
# Select one typeB target
|
||||
4A010300
|
||||
|
||||
# SELECT AID "1TIC.ICA"
|
||||
4001 00a4 0400 08 315449432e494341
|
||||
|
||||
# Select ICC file
|
||||
4001 80a4 0800 04 3f00 0002
|
||||
4001 00a4 0000 02 3f00
|
||||
4001 00a4 0000 02 0002
|
||||
#ICC:
|
||||
4001 80b2 0104 1d
|
||||
4001 00b2 0104 1d
|
||||
|
||||
# Select Holder file
|
||||
4001 80a4 0800 04 3f00 3f1c
|
||||
4001 00a4 0000 02 3f1c
|
||||
#Holder1:
|
||||
4001 80b2 0104 1d
|
||||
4001 00b2 0104 1d
|
||||
#Holder2:
|
||||
4001 80b2 0204 1d
|
||||
4001 00b2 0204 1d
|
||||
|
||||
# Select EnvHol file
|
||||
4001 00a4 0800 04 2000 2001
|
||||
4001 00a4 0000 00
|
||||
4001 00a4 0000 02 2000
|
||||
4001 00a4 0000 02 2001
|
||||
#EnvHol1:
|
||||
4001 00b2 0104 1d
|
||||
#EnvHol2:
|
||||
4001 00b2 0204 1d
|
||||
|
||||
# Select EvLog file
|
||||
4001 00a4 0800 04 2000 2010
|
||||
4001 00a4 0000 02 2010
|
||||
#EvLog1:
|
||||
4001 00b2 0104 1d
|
||||
#EvLog2:
|
||||
@ -50,12 +58,12 @@ cat << EOF | \
|
||||
4001 00b2 0304 1d
|
||||
|
||||
# Select ConList file
|
||||
4001 00a4 0800 04 2000 2050
|
||||
4001 00a4 0000 02 2050
|
||||
#ConList:
|
||||
4001 00b2 0104 1d
|
||||
|
||||
# Select Contra file
|
||||
4001 00a4 0800 04 2000 2020
|
||||
4001 00a4 0000 02 2020
|
||||
#Contra1:
|
||||
4001 00b2 0104 1d
|
||||
#Contra2:
|
||||
@ -82,17 +90,19 @@ cat << EOF | \
|
||||
4001 00b2 0c04 1d
|
||||
|
||||
# Select Counter file
|
||||
4001 00a4 0800 04 2000 2069
|
||||
4001 00a4 0000 02 2069
|
||||
#Counter:
|
||||
4001 00b2 0104 1d
|
||||
|
||||
# Select LoadLog file
|
||||
4001 00a4 0800 04 1000 1014
|
||||
4001 00a4 0000 00
|
||||
4001 00a4 0000 02 1000
|
||||
4001 00a4 0000 02 1014
|
||||
#LoadLog:
|
||||
4001 00b2 0104 1d
|
||||
|
||||
# Select Purcha file
|
||||
4001 00a4 08 0004 1000 1015
|
||||
4001 00a4 0000 02 1015
|
||||
#Purcha1:
|
||||
4001 00b2 0104 1d
|
||||
#Purcha2:
|
||||
@ -101,7 +111,9 @@ cat << EOF | \
|
||||
4001 00b2 0304 1d
|
||||
|
||||
# Select SpecEv file
|
||||
4001 00a4 08 0004 2000 2040
|
||||
4001 00a4 0000 00
|
||||
4001 00a4 0000 02 2000
|
||||
4001 00a4 0000 02 2040
|
||||
#SpecEv1:
|
||||
4001 00b2 0104 1d
|
||||
#SpecEv2:
|
||||
|
||||
@ -68,7 +68,7 @@ Please report any bugs on the
|
||||
.B libnfc
|
||||
issue tracker at:
|
||||
.br
|
||||
.BR http://code.google.com/p/libnfc/issues
|
||||
.BR https://github.com/nfc-tools/libnfc/issues
|
||||
.SH LICENCE
|
||||
.B libnfc
|
||||
is licensed under the GNU Lesser General Public License (LGPL), version 3.
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||
* See AUTHORS file for a more comprehensive list of contributors.
|
||||
* Additional contributors of this file:
|
||||
* Copyright (C) 2020 Adam Laurie
|
||||
*
|
||||
* 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
|
||||
@ -234,6 +235,14 @@ typedef struct {
|
||||
uint8_t abtAtr[33];
|
||||
} nfc_iso14443bi_info;
|
||||
|
||||
/**
|
||||
* @struct nfc_iso14443biclass_info
|
||||
* @brief NFC ISO14443BiClass tag information
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t abtUID[8];
|
||||
} nfc_iso14443biclass_info;
|
||||
|
||||
/**
|
||||
* @struct nfc_iso14443b2sr_info
|
||||
* @brief NFC ISO14443-2B ST SRx tag information
|
||||
@ -261,6 +270,15 @@ typedef struct {
|
||||
uint8_t btId[4];
|
||||
} nfc_jewel_info;
|
||||
|
||||
/**
|
||||
* @struct nfc_barcode_info
|
||||
* @brief Thinfilm NFC Barcode information
|
||||
*/
|
||||
typedef struct {
|
||||
size_t szDataLen;
|
||||
uint8_t abtData[32];
|
||||
} nfc_barcode_info;
|
||||
|
||||
/**
|
||||
* @union nfc_target_info
|
||||
* @brief Union between all kind of tags information structures.
|
||||
@ -274,6 +292,8 @@ typedef union {
|
||||
nfc_iso14443b2ct_info nci;
|
||||
nfc_jewel_info nji;
|
||||
nfc_dep_info ndi;
|
||||
nfc_barcode_info nti; // "t" for Thinfilm, "b" already used
|
||||
nfc_iso14443biclass_info nhi; // hid iclass / picopass - nii already used
|
||||
} nfc_target_info;
|
||||
|
||||
/**
|
||||
@ -301,6 +321,9 @@ typedef enum {
|
||||
NMT_ISO14443B2CT, // ISO14443-2B ASK CTx
|
||||
NMT_FELICA,
|
||||
NMT_DEP,
|
||||
NMT_BARCODE, // Thinfilm NFC Barcode
|
||||
NMT_ISO14443BICLASS, // HID iClass 14443B mode
|
||||
NMT_END_ENUM = NMT_ISO14443BICLASS, // dummy for sizing - always should alias last
|
||||
} nfc_modulation_type;
|
||||
|
||||
/**
|
||||
|
||||
@ -28,14 +28,12 @@
|
||||
* @file nfc.h
|
||||
* @brief libnfc interface
|
||||
*
|
||||
* Provide all usefull functions (API) to handle NFC devices.
|
||||
* Provide all useful functions (API) to handle NFC devices.
|
||||
*/
|
||||
|
||||
#ifndef _LIBNFC_H_
|
||||
# define _LIBNFC_H_
|
||||
|
||||
# include <sys/time.h>
|
||||
|
||||
# include <stdint.h>
|
||||
# include <stdbool.h>
|
||||
|
||||
@ -127,6 +125,7 @@ NFC_EXPORT const char *nfc_device_get_name(nfc_device *pnd);
|
||||
NFC_EXPORT const char *nfc_device_get_connstring(nfc_device *pnd);
|
||||
NFC_EXPORT int nfc_device_get_supported_modulation(nfc_device *pnd, const nfc_mode mode, const nfc_modulation_type **const supported_mt);
|
||||
NFC_EXPORT int nfc_device_get_supported_baud_rate(nfc_device *pnd, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br);
|
||||
NFC_EXPORT int nfc_device_get_supported_baud_rate_target_mode(nfc_device *pnd, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br);
|
||||
|
||||
/* Properties accessors */
|
||||
NFC_EXPORT int nfc_device_set_property_int(nfc_device *pnd, const nfc_property property, const int value);
|
||||
|
||||
@ -5,6 +5,9 @@ IF(WIN32)
|
||||
|
||||
# Add in the rc for version information in the dll
|
||||
LIST(APPEND WINDOWS_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/../windows/libnfc.rc)
|
||||
IF (NOT MINGW)
|
||||
LIST(APPEND WINDOWS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc_msvc.def)
|
||||
ENDIF()
|
||||
ENDIF(WIN32)
|
||||
|
||||
# Library's chips
|
||||
@ -26,37 +29,27 @@ IF(UART_REQUIRED)
|
||||
ENDIF(UART_REQUIRED)
|
||||
|
||||
IF(I2C_REQUIRED)
|
||||
IF(WIN32)
|
||||
# Windows is not supported at the moment
|
||||
#LIST(APPEND BUSES_SOURCES ../contrib/win32/libnfc/buses/i2c)
|
||||
MESSAGE( FATAL_ERROR "I2C not (yet) supported under Windows!" )
|
||||
ELSE(WIN32)
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
LIST(APPEND BUSES_SOURCES buses/i2c)
|
||||
ENDIF(WIN32)
|
||||
ELSE(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
# Only Linux is supported at the moment
|
||||
#LIST(APPEND BUSES_SOURCES ../contrib/win32/libnfc/buses/i2c)
|
||||
MESSAGE( FATAL_ERROR "I2C is only (yet) supported in Linux!" )
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
ENDIF(I2C_REQUIRED)
|
||||
|
||||
IF(SPI_REQUIRED)
|
||||
IF(WIN32)
|
||||
# Windows is not supported at the moment
|
||||
#LIST(APPEND BUSES_SOURCES ../contrib/win32/libnfc/buses/spi)
|
||||
MESSAGE( FATAL_ERROR "SPI not (yet) supported under Windows!" )
|
||||
ELSE(WIN32)
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
LIST(APPEND BUSES_SOURCES buses/spi)
|
||||
ENDIF(WIN32)
|
||||
ELSE(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
# Only Linux is supported at the moment
|
||||
#LIST(APPEND BUSES_SOURCES ../contrib/win32/libnfc/buses/spi)
|
||||
MESSAGE( FATAL_ERROR "SPI is only (yet) supported in Linux!" )
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
ENDIF(SPI_REQUIRED)
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/buses)
|
||||
|
||||
IF(WIN32)
|
||||
# Windows now requires regex, so we utilize PCRE
|
||||
# since Windows doesn't get the benefit of finding in CMake
|
||||
# it has to be added manually
|
||||
IF(PCRE_FOUND)
|
||||
INCLUDE_DIRECTORIES(${PCRE_INCLUDE_DIRS})
|
||||
LINK_DIRECTORIES(${PCRE_LIBRARY_DIRS})
|
||||
ENDIF(PCRE_FOUND)
|
||||
ENDIF(WIN32)
|
||||
|
||||
IF(PCSC_FOUND)
|
||||
INCLUDE_DIRECTORIES(${PCSC_INCLUDE_DIRS})
|
||||
LINK_DIRECTORIES(${PCSC_LIBRARY_DIRS})
|
||||
@ -73,7 +66,9 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
IF(LIBNFC_LOG)
|
||||
IF(WIN32)
|
||||
SET(CMAKE_C_FLAGS "-fgnu89-inline ${CMAKE_C_FLAGS}")
|
||||
IF(MINGW)
|
||||
SET(CMAKE_C_FLAGS "-fgnu89-inline ${CMAKE_C_FLAGS}")
|
||||
ENDIF(MINGW)
|
||||
LIST(APPEND LIBRARY_SOURCES log ../contrib/win32/libnfc/log-internal)
|
||||
ELSE(WIN32)
|
||||
LIST(APPEND LIBRARY_SOURCES log log-internal)
|
||||
@ -89,21 +84,25 @@ IF(LIBUSB_FOUND)
|
||||
TARGET_LINK_LIBRARIES(nfc ${LIBUSB_LIBRARIES})
|
||||
ENDIF(LIBUSB_FOUND)
|
||||
|
||||
SET_TARGET_PROPERTIES(nfc PROPERTIES SOVERSION 0)
|
||||
IF(LIBRT_FOUND)
|
||||
TARGET_LINK_LIBRARIES(nfc ${LIBRT_LIBRARIES})
|
||||
ENDIF(LIBRT_FOUND)
|
||||
|
||||
SET_TARGET_PROPERTIES(nfc PROPERTIES SOVERSION 6 VERSION 6.0.0)
|
||||
|
||||
IF(WIN32)
|
||||
# Libraries that are windows specific
|
||||
TARGET_LINK_LIBRARIES(nfc wsock32)
|
||||
IF(PCRE_FOUND)
|
||||
TARGET_LINK_LIBRARIES(nfc ${PCRE_LIBRARIES})
|
||||
ENDIF(PCRE_FOUND)
|
||||
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT libnfc.lib
|
||||
COMMAND dlltool -d ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc.def -l ${CMAKE_CURRENT_BINARY_DIR}/libnfc.lib ${CMAKE_CURRENT_BINARY_DIR}/libnfc.dll
|
||||
DEPENDS nfc ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc.def
|
||||
)
|
||||
ADD_CUSTOM_TARGET(win32lib ALL DEPENDS libnfc.lib)
|
||||
IF(MINGW)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT libnfc.lib
|
||||
COMMAND ${DLLTOOL} -d ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc.def -l ${CMAKE_CURRENT_BINARY_DIR}/libnfc.lib ${CMAKE_CURRENT_BINARY_DIR}/libnfc.dll
|
||||
DEPENDS nfc ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/nfc.def
|
||||
)
|
||||
ADD_CUSTOM_TARGET(win32lib ALL DEPENDS libnfc.lib)
|
||||
ELSE()
|
||||
ADD_LIBRARY(win32lib ALIAS nfc)
|
||||
ENDIF()
|
||||
|
||||
# On Windows the shared (runtime) library should be either in the same
|
||||
# directory as the excutables or in the path, we add it to same directory
|
||||
|
||||
@ -22,7 +22,7 @@ libnfc_la_SOURCES = \
|
||||
nfc-internal.h \
|
||||
target-subr.h
|
||||
|
||||
libnfc_la_LDFLAGS = -no-undefined -version-info 5:1:0 -export-symbols-regex '^nfc_|^iso14443a_|^str_nfc_|pn53x_transceive|pn532_SAMConfiguration|pn53x_read_register|pn53x_write_register'
|
||||
libnfc_la_LDFLAGS = -no-undefined -version-info 6:0:0 -export-symbols-regex '^nfc_|^iso14443a_|^iso14443b_|^str_nfc_|pn53x_transceive|pn532_SAMConfiguration|pn53x_read_register|pn53x_write_register'
|
||||
libnfc_la_CFLAGS = @DRIVERS_CFLAGS@
|
||||
libnfc_la_LIBADD = \
|
||||
$(top_builddir)/libnfc/chips/libnfcchips.la \
|
||||
@ -44,4 +44,5 @@ if WITH_LOG
|
||||
endif
|
||||
|
||||
EXTRA_DIST = \
|
||||
CMakeLists.txt
|
||||
CMakeLists.txt \
|
||||
additional-pages.dox
|
||||
|
||||
@ -135,6 +135,8 @@ i2c_read(i2c_device id, uint8_t *pbtRx, const size_t szRx)
|
||||
|
||||
if (recCount < 0) {
|
||||
res = NFC_EIO;
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
|
||||
"Error: read only %d bytes (%d expected) (%s).", (int)recCount, (int) szRx, strerror(errno));
|
||||
} else {
|
||||
if (recCount < (ssize_t)szRx) {
|
||||
res = NFC_EINVARG;
|
||||
@ -167,7 +169,7 @@ i2c_write(i2c_device id, const uint8_t *pbtTx, const size_t szTx)
|
||||
return NFC_SUCCESS;
|
||||
} else {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
|
||||
"Error: wrote only %d bytes (%d expected).", (int)writeCount, (int) szTx);
|
||||
"Error: wrote only %d bytes (%d expected) (%s).", (int)writeCount, (int) szTx, strerror(errno));
|
||||
return NFC_EIO;
|
||||
}
|
||||
}
|
||||
@ -189,29 +191,27 @@ i2c_list_ports(void)
|
||||
size_t szRes = 1;
|
||||
|
||||
res[0] = NULL;
|
||||
DIR *dir;
|
||||
if ((dir = opendir("/dev")) == NULL) {
|
||||
DIR *pdDir;
|
||||
if ((pdDir = opendir("/dev")) == NULL) {
|
||||
perror("opendir error: /dev");
|
||||
return res;
|
||||
}
|
||||
struct dirent entry;
|
||||
struct dirent *result;
|
||||
|
||||
while ((readdir_r(dir, &entry, &result) == 0) && (result != NULL)) {
|
||||
struct dirent *pdDirEnt;
|
||||
while ((pdDirEnt = readdir(pdDir)) != NULL) {
|
||||
const char **p = i2c_ports_device_radix;
|
||||
while (*p) {
|
||||
if (!strncmp(entry.d_name, *p, strlen(*p))) {
|
||||
if (!strncmp(pdDirEnt->d_name, *p, strlen(*p))) {
|
||||
char **res2 = realloc(res, (szRes + 1) * sizeof(char *));
|
||||
if (!res2) {
|
||||
perror("malloc");
|
||||
goto oom;
|
||||
}
|
||||
res = res2;
|
||||
if (!(res[szRes - 1] = malloc(6 + strlen(entry.d_name)))) {
|
||||
if (!(res[szRes - 1] = malloc(6 + strlen(pdDirEnt->d_name)))) {
|
||||
perror("malloc");
|
||||
goto oom;
|
||||
}
|
||||
sprintf(res[szRes - 1], "/dev/%s", entry.d_name);
|
||||
sprintf(res[szRes - 1], "/dev/%s", pdDirEnt->d_name);
|
||||
|
||||
szRes++;
|
||||
res[szRes - 1] = NULL;
|
||||
@ -220,7 +220,7 @@ i2c_list_ports(void)
|
||||
}
|
||||
}
|
||||
oom:
|
||||
closedir(dir);
|
||||
closedir(pdDir);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -196,7 +196,7 @@ spi_send_receive(spi_port sp, const uint8_t *pbtTx, const size_t szTx, uint8_t *
|
||||
struct spi_ioc_transfer tr_send = {
|
||||
.tx_buf = (unsigned long) pbtTx,
|
||||
.rx_buf = 0,
|
||||
.len = szTx ,
|
||||
.len = szTx,
|
||||
.delay_usecs = 0,
|
||||
.speed_hz = 0,
|
||||
.bits_per_word = 0,
|
||||
@ -283,10 +283,7 @@ spi_list_ports(void)
|
||||
|
||||
DIR *pdDir = opendir("/dev");
|
||||
struct dirent *pdDirEnt;
|
||||
struct dirent entry;
|
||||
struct dirent *result;
|
||||
while ((readdir_r(pdDir, &entry, &result) == 0) && (result != NULL)) {
|
||||
pdDirEnt = &entry;
|
||||
while ((pdDirEnt = readdir(pdDir)) != NULL) {
|
||||
#if !defined(__APPLE__)
|
||||
if (!isdigit(pdDirEnt->d_name[strlen(pdDirEnt->d_name) - 1]))
|
||||
continue;
|
||||
|
||||
@ -74,15 +74,24 @@
|
||||
#endif
|
||||
|
||||
# if defined(__APPLE__)
|
||||
const char *serial_ports_device_radix[] = { "tty.SLAB_USBtoUART", "tty.usbserial-", NULL };
|
||||
const char *serial_ports_device_radix[] = { "tty.SLAB_USBtoUART", "tty.usbserial", "tty.usbmodem", NULL };
|
||||
# elif defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__FreeBSD_kernel__)
|
||||
const char *serial_ports_device_radix[] = { "cuaU", "cuau", NULL };
|
||||
# elif defined (__linux__)
|
||||
# elif defined (__NetBSD__)
|
||||
const char *serial_ports_device_radix[] = { "tty0", "ttyC", "ttyS", "ttyU", "ttyY", NULL };
|
||||
# elif defined (__linux__) || defined (__CYGWIN__)
|
||||
const char *serial_ports_device_radix[] = { "ttyUSB", "ttyS", "ttyACM", "ttyAMA", "ttyO", NULL };
|
||||
# else
|
||||
# error "Can't determine serial string for your system"
|
||||
# endif
|
||||
|
||||
// As of 2015/Feb/22, Cygwin does not handle FIONREAD on physical serial devices.
|
||||
// We'll use TIOCINQ instead which is pretty much the same.
|
||||
#ifdef __CYGWIN__
|
||||
# include <sys/termios.h>
|
||||
# define FIONREAD TIOCINQ
|
||||
#endif
|
||||
|
||||
// Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct
|
||||
# define CCLAIMED 0x80000000
|
||||
|
||||
@ -179,7 +188,7 @@ uart_flush_input(serial_port sp, bool wait)
|
||||
void
|
||||
uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
||||
{
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Serial port speed requested to be set to %d baud.", uiPortSpeed);
|
||||
|
||||
// Portability note: on some systems, B9600 != 9600 so we have to do
|
||||
// uint32_t <=> speed_t associations by hand.
|
||||
@ -215,7 +224,7 @@ uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
||||
break;
|
||||
# endif
|
||||
default:
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to set serial port speed to %d bauds. Speed value must be one of those defined in termios(3).",
|
||||
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 those defined in termios(3).",
|
||||
uiPortSpeed);
|
||||
return;
|
||||
};
|
||||
@ -385,32 +394,31 @@ uart_list_ports(void)
|
||||
size_t szRes = 1;
|
||||
|
||||
res[0] = NULL;
|
||||
DIR *dir;
|
||||
if ((dir = opendir("/dev")) == NULL) {
|
||||
DIR *pdDir;
|
||||
if ((pdDir = opendir("/dev")) == NULL) {
|
||||
perror("opendir error: /dev");
|
||||
return res;
|
||||
}
|
||||
struct dirent entry;
|
||||
struct dirent *result;
|
||||
while ((readdir_r(dir, &entry, &result) == 0) && (result != NULL)) {
|
||||
struct dirent *pdDirEnt;
|
||||
while ((pdDirEnt = readdir(pdDir)) != NULL) {
|
||||
#if !defined(__APPLE__)
|
||||
if (!isdigit(entry.d_name[strlen(entry.d_name) - 1]))
|
||||
if (!isdigit(pdDirEnt->d_name[strlen(pdDirEnt->d_name) - 1]))
|
||||
continue;
|
||||
#endif
|
||||
const char **p = serial_ports_device_radix;
|
||||
while (*p) {
|
||||
if (!strncmp(entry.d_name, *p, strlen(*p))) {
|
||||
if (!strncmp(pdDirEnt->d_name, *p, strlen(*p))) {
|
||||
char **res2 = realloc(res, (szRes + 1) * sizeof(char *));
|
||||
if (!res2) {
|
||||
perror("malloc");
|
||||
goto oom;
|
||||
}
|
||||
res = res2;
|
||||
if (!(res[szRes - 1] = malloc(6 + strlen(entry.d_name)))) {
|
||||
if (!(res[szRes - 1] = malloc(6 + strlen(pdDirEnt->d_name)))) {
|
||||
perror("malloc");
|
||||
goto oom;
|
||||
}
|
||||
sprintf(res[szRes - 1], "/dev/%s", entry.d_name);
|
||||
sprintf(res[szRes - 1], "/dev/%s", pdDirEnt->d_name);
|
||||
|
||||
szRes++;
|
||||
res[szRes - 1] = NULL;
|
||||
@ -419,7 +427,7 @@ uart_list_ports(void)
|
||||
}
|
||||
}
|
||||
oom:
|
||||
closedir(dir);
|
||||
closedir(pdDir);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -33,7 +33,9 @@
|
||||
#ifndef __NFC_BUS_UART_H__
|
||||
# define __NFC_BUS_UART_H__
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
|
||||
#ifndef _WIN32
|
||||
// Under POSIX system, we use libusb (>= 0.1.12)
|
||||
#include <stdint.h>
|
||||
#include <usb.h>
|
||||
#define USB_TIMEDOUT ETIMEDOUT
|
||||
#define _usb_strerror( X ) strerror(-X)
|
||||
|
||||
@ -81,32 +81,38 @@
|
||||
#define TgGetTargetStatus 0x8A
|
||||
|
||||
/** @note PN53x's normal frame:
|
||||
* See the PN532 (firmware) user manual, section 6.2.1.1: Normal information
|
||||
* frame, figure 13. Normal information frame, page 28 rev. 02 - 2007-11-07.
|
||||
*
|
||||
* .-- Start
|
||||
* | .-- Packet length
|
||||
* | | .-- Length checksum
|
||||
* | | | .-- Direction (D4 Host to PN, D5 PN to Host)
|
||||
* | | | | .-- Code
|
||||
* | | | | | .-- Packet checksum
|
||||
* | | | | | | .-- Postamble
|
||||
* V | | | | | |
|
||||
* ----- V V V V V V
|
||||
* 00 FF 02 FE D4 02 2A 00
|
||||
* .-- Preamble
|
||||
* | .-- Start
|
||||
* | | .-- Packet length
|
||||
* | | | .-- Length checksum
|
||||
* | | | | .-- Direction (D4 Host to PN, D5 PN to Host)
|
||||
* | | | | | .-- Code
|
||||
* | | | | | | .-- Packet checksum
|
||||
* | | | | | | | .-- Postamble
|
||||
* | V | | | | | |
|
||||
* V ----- V V V V V V
|
||||
* 00 00 FF 02 FE D4 02 2A 00
|
||||
*/
|
||||
|
||||
/** @note PN53x's extended frame:
|
||||
* See the PN532 (firmware) user manual, section 6.2.1.2: Extended information
|
||||
* frame, figure 14. Normal information frame, page 29 rev. 02 - 2007-11-07.
|
||||
*
|
||||
* .-- Start
|
||||
* | .-- Fixed to FF to enable extended frame
|
||||
* | | .-- Packet length
|
||||
* | | | .-- Length checksum
|
||||
* | | | | .-- Direction (D4 Host to PN, D5 PN to Host)
|
||||
* | | | | | .-- Code
|
||||
* | | | | | | .-- Packet checksum
|
||||
* | | | | | | | .-- Postamble
|
||||
* V V V | | | | |
|
||||
* ----- ----- ----- V V V V V
|
||||
* 00 FF FF FF 00 02 FE D4 02 2A 00
|
||||
* .-- Preamble
|
||||
* | .-- Start
|
||||
* | | .-- Fixed to FF to enable extended frame
|
||||
* | | | .-- Packet length
|
||||
* | | | | .-- Length checksum
|
||||
* | | | | | .-- Direction (D4 Host to PN, D5 PN to Host)
|
||||
* | | | | | | .-- Code
|
||||
* | | | | | | | .-- Packet checksum
|
||||
* | | | | | | | | .-- Postamble
|
||||
* | V V V | | | | |
|
||||
* V ----- ----- ----- V V V V V
|
||||
* 00 00 FF FF FF 00 02 FE D4 02 2A 00
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||
* See AUTHORS file for a more comprehensive list of contributors.
|
||||
* Additional contributors of this file:
|
||||
* Copyright (C) 2020 Adam Laurie
|
||||
*
|
||||
* 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
|
||||
@ -52,10 +53,12 @@
|
||||
const uint8_t pn53x_ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
|
||||
const uint8_t pn53x_nack_frame[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
|
||||
static const uint8_t pn53x_error_frame[] = { 0x00, 0x00, 0xff, 0x01, 0xff, 0x7f, 0x81, 0x00 };
|
||||
const nfc_baud_rate pn53x_iso14443a_supported_baud_rates[] = { NBR_106, 0 };
|
||||
const nfc_baud_rate pn532_iso14443a_supported_baud_rates[] = { NBR_424, NBR_212, NBR_106, 0 };
|
||||
const nfc_baud_rate pn533_iso14443a_supported_baud_rates[] = { NBR_847, NBR_424, NBR_212, NBR_106, 0 };
|
||||
const nfc_baud_rate pn53x_felica_supported_baud_rates[] = { NBR_424, NBR_212, 0 };
|
||||
const nfc_baud_rate pn53x_dep_supported_baud_rates[] = { NBR_424, NBR_212, NBR_106, 0 };
|
||||
const nfc_baud_rate pn53x_jewel_supported_baud_rates[] = { NBR_106, 0 };
|
||||
const nfc_baud_rate pn53x_barcode_supported_baud_rates[] = { NBR_106, 0 };
|
||||
const nfc_baud_rate pn532_iso14443b_supported_baud_rates[] = { NBR_106, 0 };
|
||||
const nfc_baud_rate pn533_iso14443b_supported_baud_rates[] = { NBR_847, NBR_424, NBR_212, NBR_106, 0 };
|
||||
const nfc_modulation_type pn53x_supported_modulation_as_target[] = {NMT_ISO14443A, NMT_FELICA, NMT_DEP, 0};
|
||||
@ -83,7 +86,7 @@ pn53x_init(struct nfc_device *pnd)
|
||||
}
|
||||
|
||||
if (!CHIP_DATA(pnd)->supported_modulation_as_initiator) {
|
||||
CHIP_DATA(pnd)->supported_modulation_as_initiator = malloc(sizeof(nfc_modulation_type) * 9);
|
||||
CHIP_DATA(pnd)->supported_modulation_as_initiator = malloc(sizeof(nfc_modulation_type) * (NMT_END_ENUM + 1));
|
||||
if (! CHIP_DATA(pnd)->supported_modulation_as_initiator)
|
||||
return NFC_ESOFT;
|
||||
int nbSupportedModulation = 0;
|
||||
@ -96,10 +99,20 @@ pn53x_init(struct nfc_device *pnd)
|
||||
if (pnd->btSupportByte & SUPPORT_ISO14443B) {
|
||||
CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_ISO14443B;
|
||||
nbSupportedModulation++;
|
||||
CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_ISO14443BI;
|
||||
nbSupportedModulation++;
|
||||
CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_ISO14443B2SR;
|
||||
nbSupportedModulation++;
|
||||
CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_ISO14443B2CT;
|
||||
nbSupportedModulation++;
|
||||
CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_ISO14443BICLASS;
|
||||
nbSupportedModulation++;
|
||||
}
|
||||
if (CHIP_DATA(pnd)->type != PN531) {
|
||||
CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_JEWEL;
|
||||
nbSupportedModulation++;
|
||||
CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_BARCODE;
|
||||
nbSupportedModulation++;
|
||||
}
|
||||
CHIP_DATA(pnd)->supported_modulation_as_initiator[nbSupportedModulation] = NMT_DEP;
|
||||
nbSupportedModulation++;
|
||||
@ -364,7 +377,6 @@ int
|
||||
pn53x_wrap_frame(const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar,
|
||||
uint8_t *pbtFrame)
|
||||
{
|
||||
uint8_t btFrame;
|
||||
uint8_t btData;
|
||||
uint32_t uiBitPos;
|
||||
uint32_t uiDataPos = 0;
|
||||
@ -391,7 +403,7 @@ pn53x_wrap_frame(const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbt
|
||||
// air-bytes = mirror(buffer-byte) + mirror(buffer-byte) + mirror(buffer-byte) + ..
|
||||
while (true) {
|
||||
// Reset the temporary frame byte;
|
||||
btFrame = 0;
|
||||
uint8_t btFrame = 0;
|
||||
|
||||
for (uiBitPos = 0; uiBitPos < 8; uiBitPos++) {
|
||||
// Copy as much data that fits in the frame byte
|
||||
@ -566,6 +578,12 @@ pn53x_decode_target_data(const uint8_t *pbtRawData, size_t szRawData, pn53x_type
|
||||
memcpy(pnti->nsi.abtUID, pbtRawData, 8);
|
||||
break;
|
||||
|
||||
case NMT_ISO14443BICLASS:
|
||||
// Store the UID
|
||||
for (uint8_t i = 0 ; i < 8 ; ++i)
|
||||
pnti->nhi.abtUID[7 - i] = pbtRawData[i];
|
||||
break;
|
||||
|
||||
case NMT_ISO14443B2CT:
|
||||
// Store UID LSB
|
||||
memcpy(pnti->nci.abtUID, pbtRawData, 2);
|
||||
@ -604,10 +622,13 @@ pn53x_decode_target_data(const uint8_t *pbtRawData, size_t szRawData, pn53x_type
|
||||
pbtRawData += 2;
|
||||
memcpy(pnti->nji.btId, pbtRawData, 4);
|
||||
break;
|
||||
// Should not happend...
|
||||
case NMT_BARCODE:
|
||||
pnti->nti.szDataLen = szRawData;
|
||||
memcpy(pnti->nti.abtData, pbtRawData, szRawData);
|
||||
break;
|
||||
// Should not happend...
|
||||
case NMT_DEP:
|
||||
return NFC_ECHIP;
|
||||
break;
|
||||
}
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
@ -820,12 +841,10 @@ pn53x_set_property_int(struct nfc_device *pnd, const nfc_property property, cons
|
||||
case NP_TIMEOUT_ATR:
|
||||
CHIP_DATA(pnd)->timeout_atr = value;
|
||||
return pn53x_RFConfiguration__Various_timings(pnd, pn53x_int_to_timeout(CHIP_DATA(pnd)->timeout_atr), pn53x_int_to_timeout(CHIP_DATA(pnd)->timeout_communication));
|
||||
break;
|
||||
case NP_TIMEOUT_COM:
|
||||
CHIP_DATA(pnd)->timeout_communication = value;
|
||||
return pn53x_RFConfiguration__Various_timings(pnd, pn53x_int_to_timeout(CHIP_DATA(pnd)->timeout_atr), pn53x_int_to_timeout(CHIP_DATA(pnd)->timeout_communication));
|
||||
break;
|
||||
// Following properties are invalid (not integer)
|
||||
// Following properties are invalid (not integer)
|
||||
case NP_HANDLE_CRC:
|
||||
case NP_HANDLE_PARITY:
|
||||
case NP_ACTIVATE_FIELD:
|
||||
@ -863,7 +882,6 @@ pn53x_set_property_bool(struct nfc_device *pnd, const nfc_property property, con
|
||||
return res;
|
||||
pnd->bCrc = bEnable;
|
||||
return NFC_SUCCESS;
|
||||
break;
|
||||
|
||||
case NP_HANDLE_PARITY:
|
||||
// Handle parity bit by PN53X chip or parse it as data bit
|
||||
@ -875,21 +893,17 @@ pn53x_set_property_bool(struct nfc_device *pnd, const nfc_property property, con
|
||||
return res;
|
||||
pnd->bPar = bEnable;
|
||||
return NFC_SUCCESS;
|
||||
break;
|
||||
|
||||
case NP_EASY_FRAMING:
|
||||
pnd->bEasyFraming = bEnable;
|
||||
return NFC_SUCCESS;
|
||||
break;
|
||||
|
||||
case NP_ACTIVATE_FIELD:
|
||||
return pn53x_RFConfiguration__RF_field(pnd, bEnable);
|
||||
break;
|
||||
|
||||
case NP_ACTIVATE_CRYPTO1:
|
||||
btValue = (bEnable) ? SYMBOL_MF_CRYPTO1_ON : 0x00;
|
||||
return pn53x_write_register(pnd, PN53X_REG_CIU_Status2, SYMBOL_MF_CRYPTO1_ON, btValue);
|
||||
break;
|
||||
|
||||
case NP_INFINITE_SELECT:
|
||||
// TODO Made some research around this point:
|
||||
@ -901,17 +915,14 @@ pn53x_set_property_bool(struct nfc_device *pnd, const nfc_property property, con
|
||||
(bEnable) ? 0xff : 0x01, // MxRtyPSL, default: 0x01
|
||||
(bEnable) ? 0xff : 0x02 // MxRtyPassiveActivation, default: 0xff (0x00 leads to problems with PN531)
|
||||
);
|
||||
break;
|
||||
|
||||
case NP_ACCEPT_INVALID_FRAMES:
|
||||
btValue = (bEnable) ? SYMBOL_RX_NO_ERROR : 0x00;
|
||||
return pn53x_write_register(pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_NO_ERROR, btValue);
|
||||
break;
|
||||
|
||||
case NP_ACCEPT_MULTIPLE_FRAMES:
|
||||
btValue = (bEnable) ? SYMBOL_RX_MULTIPLE : 0x00;
|
||||
return pn53x_write_register(pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_MULTIPLE, btValue);
|
||||
break;
|
||||
|
||||
case NP_AUTO_ISO14443_4:
|
||||
if (bEnable == pnd->bAutoIso14443_4)
|
||||
@ -919,7 +930,6 @@ pn53x_set_property_bool(struct nfc_device *pnd, const nfc_property property, con
|
||||
return NFC_SUCCESS;
|
||||
pnd->bAutoIso14443_4 = bEnable;
|
||||
return pn53x_set_parameters(pnd, PARAM_AUTO_RATS, bEnable);
|
||||
break;
|
||||
|
||||
case NP_FORCE_ISO14443_A:
|
||||
if (!bEnable) {
|
||||
@ -935,7 +945,6 @@ pn53x_set_property_bool(struct nfc_device *pnd, const nfc_property property, con
|
||||
}
|
||||
// Set the PN53X to force 100% ASK Modified miller decoding (default for 14443A cards)
|
||||
return pn53x_write_register(pnd, PN53X_REG_CIU_TxAuto, SYMBOL_FORCE_100_ASK, 0x40);
|
||||
break;
|
||||
|
||||
case NP_FORCE_ISO14443_B:
|
||||
if (!bEnable) {
|
||||
@ -947,7 +956,6 @@ pn53x_set_property_bool(struct nfc_device *pnd, const nfc_property property, con
|
||||
return res;
|
||||
}
|
||||
return pn53x_write_register(pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_FRAMING, 0x03);
|
||||
break;
|
||||
|
||||
case NP_FORCE_SPEED_106:
|
||||
if (!bEnable) {
|
||||
@ -959,13 +967,11 @@ pn53x_set_property_bool(struct nfc_device *pnd, const nfc_property property, con
|
||||
return res;
|
||||
}
|
||||
return pn53x_write_register(pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_SPEED, 0x00);
|
||||
break;
|
||||
// Following properties are invalid (not boolean)
|
||||
// Following properties are invalid (not boolean)
|
||||
case NP_TIMEOUT_COMMAND:
|
||||
case NP_TIMEOUT_ATR:
|
||||
case NP_TIMEOUT_COM:
|
||||
return NFC_EINVARG;
|
||||
break;
|
||||
}
|
||||
|
||||
return NFC_EINVARG;
|
||||
@ -1051,6 +1057,56 @@ pn53x_initiator_init(struct nfc_device *pnd)
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
// iclass requires special modulation settings
|
||||
void pn53x_initiator_init_iclass_modulation(struct nfc_device *pnd)
|
||||
{
|
||||
// send a bunch of low level commands reverse engineered from a working iClass reader
|
||||
// original device was using a PN512
|
||||
//
|
||||
// // TxModeReg - Defines the data rate and framing during transmission.
|
||||
//// set bit 4 for target mode? - RxWaitRF Set to logic 1, the counter for RxWait starts only if an external RF field is detected in Target mode for NFCIP-1 or in Card Communication mode
|
||||
//pn512_write_register(0x12, "\x03", 1, false);
|
||||
pn53x_WriteRegister(pnd, PN53X_REG_CIU_TxMode, 0x03);
|
||||
//
|
||||
// // RxModeReg - Defines the data rate and framing during reception.
|
||||
//pn512_write_register(0x13, "\x03", 1, false);
|
||||
// addy changed to set bit 3 - RxNoErr (put data in fifo before flagging read end)
|
||||
//pn512_write_register(0x13, "\x0B", 1, false);
|
||||
pn53x_WriteRegister(pnd, PN53X_REG_CIU_RxMode, 0x0B);
|
||||
|
||||
// ManualRCVReg - Allows manual fine tuning of the internal receiver.
|
||||
//pn512_write_register(0x1d, "\x10", 1, false);
|
||||
pn53x_WriteRegister(pnd, PN53X_REG_CIU_ManualRCV, 0x10);
|
||||
|
||||
// RFCfgReg - Configures the receiver gain and RF level detector sensitivity.
|
||||
//pn512_write_register(0x26, "\x70", 1, false);
|
||||
pn53x_WriteRegister(pnd, PN53X_REG_CIU_RFCfg, 0x70);
|
||||
|
||||
// GsNOffReg - Selects the conductance for the N-driver of the antenna driver pins TX1 and TX2 when the driver is switched off.
|
||||
//pn512_write_register(0x23, "\x88", 1, false);
|
||||
pn53x_WriteRegister(pnd, PN53X_REG_CIU_GsNOFF, 0x88);
|
||||
|
||||
// GsNOnReg - Selects the conductance for the N-driver of the antenna driver pins TX1 and TX2 when the driver is switched on.
|
||||
//pn512_write_register(0x27, "\xf8", 1, false);
|
||||
pn53x_WriteRegister(pnd, PN53X_REG_CIU_GsNOn, 0xf8);
|
||||
|
||||
// CWGsPReg - Defines the conductance of the P-driver during times of no modulation.
|
||||
//pn512_write_register(0x28, "\x3f", 1, false);
|
||||
pn53x_WriteRegister(pnd, PN53X_REG_CIU_CWGsP, 0x3f);
|
||||
|
||||
// ModGsPReg - Defines the driver P-output conductance during modulation.
|
||||
//pn512_write_register(0x29, "\x10", 1, false);
|
||||
pn53x_WriteRegister(pnd, PN53X_REG_CIU_ModGsP, 0x10);
|
||||
|
||||
// TReloadReg (MSB) - Describes the MSB of the 16-bit long timer reload value.
|
||||
//pn512_write_register(0x2c, "\x69", 1, false);
|
||||
pn53x_WriteRegister(pnd, PN53X_REG_CIU_TReloadVal_hi, 0x69);
|
||||
|
||||
// TReloadReg (LSB) - Describes the LSB of the 16-bit long timer reload value.
|
||||
//pn512_write_register(0x2d, "\xf0", 1, false);
|
||||
pn53x_WriteRegister(pnd, PN53X_REG_CIU_TReloadVal_lo, 0xf0);
|
||||
}
|
||||
|
||||
int
|
||||
pn532_initiator_init_secure_element(struct nfc_device *pnd)
|
||||
{
|
||||
@ -1068,8 +1124,9 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd,
|
||||
size_t szTargetsData = sizeof(abtTargetsData);
|
||||
int res = 0;
|
||||
nfc_target nttmp;
|
||||
memset(&nttmp, 0x00, sizeof(nfc_target));
|
||||
|
||||
if (nm.nmt == NMT_ISO14443BI || nm.nmt == NMT_ISO14443B2SR || nm.nmt == NMT_ISO14443B2CT) {
|
||||
if (nm.nmt == NMT_ISO14443BI || nm.nmt == NMT_ISO14443B2SR || nm.nmt == NMT_ISO14443B2CT || nm.nmt == NMT_ISO14443BICLASS) {
|
||||
if (CHIP_DATA(pnd)->type == RCS360) {
|
||||
// TODO add support for RC-S360, at the moment it refuses to send raw frames without a first select
|
||||
pnd->last_error = NFC_ENOTIMPL;
|
||||
@ -1096,6 +1153,16 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd,
|
||||
size_t szInitiateLen = 2;
|
||||
uint8_t abtSelect[] = { 0x0e, 0x00 };
|
||||
uint8_t abtRx[1];
|
||||
uint8_t *pbtInitData = (uint8_t *) "\x0b";
|
||||
size_t szInitData = 1;
|
||||
|
||||
if ((res = pn53x_write_register(pnd, PN53X_REG_CIU_TxAuto, 0xef, 0x07)) < 0) // Initial RFOn, Tx2 RFAutoEn, Tx1 RFAutoEn
|
||||
return res;
|
||||
if ((res = pn53x_write_register(pnd, PN53X_REG_CIU_CWGsP, 0x3f, 0x3f)) < 0) // Conductance of the P-Driver
|
||||
return res;
|
||||
if ((res = pn53x_write_register(pnd, PN53X_REG_CIU_ModGsP, 0x3f, 0x12)) < 0) // Driver P-output conductance for the time of modulation
|
||||
return res;
|
||||
|
||||
// Getting random Chip_ID
|
||||
if ((res = pn53x_initiator_transceive_bytes(pnd, abtInitiate, szInitiateLen, abtRx, sizeof(abtRx), timeout)) < 0) {
|
||||
if ((res == NFC_ERFTRANS) && (CHIP_DATA(pnd)->last_status_byte == 0x01)) { // Chip timeout
|
||||
@ -1108,9 +1175,18 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd,
|
||||
return res;
|
||||
}
|
||||
szTargetsData = (size_t)res;
|
||||
if ((res = pn53x_initiator_transceive_bytes(pnd, pbtInitData, szInitData, abtTargetsData, sizeof(abtTargetsData), timeout)) < 0) {
|
||||
if ((res == NFC_ERFTRANS) && (CHIP_DATA(pnd)->last_status_byte == 0x01)) { // Chip timeout
|
||||
continue;
|
||||
} else
|
||||
return res;
|
||||
}
|
||||
szTargetsData = (size_t)res;
|
||||
} else if (nm.nmt == NMT_ISO14443B2CT) {
|
||||
// Some work to do before getting the UID...
|
||||
const uint8_t abtReqt[] = { 0x10 };
|
||||
uint8_t *pbtInitData = (uint8_t *) "\x9F\xFF\xFF";
|
||||
size_t szInitData = 3;
|
||||
// Getting product code / fab code & store it in output buffer after the serial nr we'll obtain later
|
||||
if ((res = pn53x_initiator_transceive_bytes(pnd, abtReqt, sizeof(abtReqt), abtTargetsData + 2, sizeof(abtTargetsData) - 2, timeout)) < 0) {
|
||||
if ((res == NFC_ERFTRANS) && (CHIP_DATA(pnd)->last_status_byte == 0x01)) { // Chip timeout
|
||||
@ -1119,16 +1195,13 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd,
|
||||
return res;
|
||||
}
|
||||
szTargetsData = (size_t)res;
|
||||
}
|
||||
|
||||
if ((res = pn53x_initiator_transceive_bytes(pnd, pbtInitData, szInitData, abtTargetsData, sizeof(abtTargetsData), timeout)) < 0) {
|
||||
if ((res == NFC_ERFTRANS) && (CHIP_DATA(pnd)->last_status_byte == 0x01)) { // Chip timeout
|
||||
continue;
|
||||
} else
|
||||
return res;
|
||||
}
|
||||
szTargetsData = (size_t)res;
|
||||
if (nm.nmt == NMT_ISO14443B2CT) {
|
||||
if ((res = pn53x_initiator_transceive_bytes(pnd, pbtInitData, szInitData, abtTargetsData, sizeof(abtTargetsData), timeout)) < 0) {
|
||||
if ((res == NFC_ERFTRANS) && (CHIP_DATA(pnd)->last_status_byte == 0x01)) { // Chip timeout
|
||||
continue;
|
||||
} else
|
||||
return res;
|
||||
}
|
||||
szTargetsData = (size_t)res;
|
||||
if (szTargetsData != 2)
|
||||
return 0; // Target is not ISO14443B2CT
|
||||
uint8_t abtRead[] = { 0xC4 }; // Reading UID_MSB (Read address 4)
|
||||
@ -1136,7 +1209,49 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd,
|
||||
return res;
|
||||
}
|
||||
szTargetsData = 6; // u16 UID_LSB, u8 prod code, u8 fab code, u16 UID_MSB
|
||||
} else if (nm.nmt == NMT_ISO14443BICLASS) {
|
||||
pn53x_initiator_init_iclass_modulation(pnd);
|
||||
//
|
||||
// Some work to do before getting the UID...
|
||||
// send ICLASS_ACTIVATE_ALL command - will get timeout as we don't expect response
|
||||
uint8_t abtReqt[] = { 0x0a }; // iClass ACTIVATE_ALL
|
||||
uint8_t abtAnticol[11];
|
||||
if (pn53x_initiator_transceive_bytes(pnd, abtReqt, sizeof(abtReqt), NULL, 0, timeout) < 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "got expected timeout on iClass activate all");
|
||||
//if ((res == NFC_ERFTRANS) && (CHIP_DATA(pnd)->last_status_byte == 0x01)) { // Chip timeout
|
||||
// continue;
|
||||
//} else
|
||||
// return res;
|
||||
}
|
||||
// do select - returned anticol contains 'handle' for tag if present
|
||||
abtReqt[0] = 0x0c; // iClass SELECT
|
||||
abtAnticol[0] = 0x81; // iClass ANTICOL
|
||||
if ((res = pn53x_initiator_transceive_bytes(pnd, abtReqt, sizeof(abtReqt), &abtAnticol[1], sizeof(abtAnticol) - 1, timeout)) < 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "timeout on iClass anticol");
|
||||
return res;
|
||||
}
|
||||
// write back anticol handle to get UID
|
||||
if ((res = pn53x_initiator_transceive_bytes(pnd, abtAnticol, 9, abtTargetsData, 10, timeout)) < 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "timeout on iClass get UID");
|
||||
return res;
|
||||
}
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "iClass raw UID: %02x %02x %02x %02x %02x %02x %02x %02x", abtTargetsData[0], abtTargetsData[1], abtTargetsData[2], abtTargetsData[3], abtTargetsData[4], abtTargetsData[5], abtTargetsData[6], abtTargetsData[7]);
|
||||
szTargetsData = 8;
|
||||
nttmp.nm = nm;
|
||||
if ((res = pn53x_decode_target_data(abtTargetsData, szTargetsData, CHIP_DATA(pnd)->type, nm.nmt, &(nttmp.nti))) < 0) {
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
|
||||
if ((res = pn53x_initiator_transceive_bytes(pnd, pbtInitData, szInitData, abtTargetsData, sizeof(abtTargetsData), timeout)) < 0) {
|
||||
if ((res == NFC_ERFTRANS) && (CHIP_DATA(pnd)->last_status_byte == 0x01)) { // Chip timeout
|
||||
continue;
|
||||
} else
|
||||
return res;
|
||||
}
|
||||
szTargetsData = (size_t)res;
|
||||
}
|
||||
|
||||
nttmp.nm = nm;
|
||||
if ((res = pn53x_decode_target_data(abtTargetsData, szTargetsData, CHIP_DATA(pnd)->type, nm.nmt, &(nttmp.nti))) < 0) {
|
||||
return res;
|
||||
@ -1156,10 +1271,90 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd,
|
||||
} while (pnd->bInfiniteSelect);
|
||||
if (! found)
|
||||
return 0;
|
||||
} else {
|
||||
} else if (nm.nmt == NMT_BARCODE) {
|
||||
if (CHIP_DATA(pnd)->type == RCS360) {
|
||||
// TODO add support for RC-S360, at the moment it refuses to send raw frames without a first select
|
||||
pnd->last_error = NFC_ENOTIMPL;
|
||||
return pnd->last_error;
|
||||
}
|
||||
// No native support in InListPassiveTarget so we do discovery by hand
|
||||
|
||||
// We turn RF field off first for a better detection rate but this doesn't work well with ASK LoGO
|
||||
if ((! CHIP_DATA(pnd)->progressive_field) && (res = nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, false)) < 0) {
|
||||
return res;
|
||||
}
|
||||
if ((res = nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false)) < 0) {
|
||||
return res;
|
||||
}
|
||||
if ((res = nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, false)) < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
do {
|
||||
uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||
uint8_t abtRxPar[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||
if ((res = nfc_initiator_transceive_bits(pnd, NULL, 0, NULL, abtRx, sizeof(abtRx), abtRxPar)) < 0) {
|
||||
if ((res == NFC_ERFTRANS) || (res == NFC_ECHIP)) { // Broken reception
|
||||
continue;
|
||||
} else {
|
||||
nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true);
|
||||
nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, true);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffle bits to produce NFC Barcode bitstream
|
||||
uint8_t uRemainder;
|
||||
size_t szPos;
|
||||
size_t szBytes = res / 8;
|
||||
size_t off = 0;
|
||||
uint8_t i;
|
||||
memset(abtTargetsData, 0x00, sizeof(abtTargetsData));
|
||||
// Reinject S bit
|
||||
abtTargetsData[off / 8] |= 1 << (7 - (off % 8));
|
||||
off++;
|
||||
|
||||
for (szPos = 0; szPos < szBytes; szPos++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
abtTargetsData[off / 8] |= ((abtRx[szPos] >> i) & 1) << (7 - (off % 8));
|
||||
off++;
|
||||
}
|
||||
abtTargetsData[off / 8] |= abtRxPar[szPos] << (7 - (off % 8));
|
||||
off++;
|
||||
}
|
||||
uRemainder = res % 8;
|
||||
for (i = 0; i < uRemainder; i++) {
|
||||
abtTargetsData[off / 8] |= ((abtRx[szPos] >> i) & 1) << (7 - (off % 8));
|
||||
off++;
|
||||
}
|
||||
|
||||
if (off % 128 != 0) {
|
||||
// NFC Barcode seems incomplete
|
||||
continue;
|
||||
}
|
||||
|
||||
szTargetsData = (size_t)off / 8;
|
||||
|
||||
// validate CRC
|
||||
uint8_t pbtCrc[2];
|
||||
iso14443a_crc(abtTargetsData, szTargetsData - 2, pbtCrc);
|
||||
if ((pbtCrc[1] != abtTargetsData[szTargetsData - 2]) || (pbtCrc[0] != abtTargetsData[szTargetsData - 1])) {
|
||||
continue;
|
||||
}
|
||||
nttmp.nm = nm;
|
||||
if ((res = pn53x_decode_target_data(abtTargetsData, szTargetsData, CHIP_DATA(pnd)->type, nm.nmt, &(nttmp.nti))) < 0) {
|
||||
return res;
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
} while (pnd->bInfiniteSelect);
|
||||
if (! found) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
const pn53x_modulation pm = pn53x_nm_to_pm(nm);
|
||||
if (PM_UNDEFINED == pm) {
|
||||
if ((PM_UNDEFINED == pm) || (NBR_UNDEFINED == nm.nbr)) {
|
||||
pnd->last_error = NFC_EINVARG;
|
||||
return pnd->last_error;
|
||||
}
|
||||
@ -1174,6 +1369,14 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd,
|
||||
if ((res = pn53x_decode_target_data(abtTargetsData + 1, szTargetsData - 1, CHIP_DATA(pnd)->type, nm.nmt, &(nttmp.nti))) < 0) {
|
||||
return res;
|
||||
}
|
||||
if ((nm.nmt == NMT_ISO14443A) && (nm.nbr != NBR_106)) {
|
||||
uint8_t pncmd_inpsl[4] = { InPSL, 0x01 };
|
||||
pncmd_inpsl[2] = nm.nbr - 1;
|
||||
pncmd_inpsl[3] = nm.nbr - 1;
|
||||
if ((res = pn53x_transceive(pnd, pncmd_inpsl, sizeof(pncmd_inpsl), NULL, 0, 0)) < 0) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pn53x_current_target_new(pnd, &nttmp) == NULL) {
|
||||
pnd->last_error = NFC_ESOFT;
|
||||
@ -1192,7 +1395,7 @@ pn53x_initiator_select_passive_target(struct nfc_device *pnd,
|
||||
const uint8_t *pbtInitData, const size_t szInitData,
|
||||
nfc_target *pnt)
|
||||
{
|
||||
return pn53x_initiator_select_passive_target_ext(pnd, nm, pbtInitData, szInitData, pnt, 0);
|
||||
return pn53x_initiator_select_passive_target_ext(pnd, nm, pbtInitData, szInitData, pnt, 300);
|
||||
}
|
||||
|
||||
int
|
||||
@ -1222,26 +1425,28 @@ pn53x_initiator_poll_target(struct nfc_device *pnd,
|
||||
szTargetTypes++;
|
||||
}
|
||||
nfc_target ntTargets[2];
|
||||
memset(ntTargets, 0x00, sizeof(nfc_target) * 2);
|
||||
|
||||
if ((res = pn53x_InAutoPoll(pnd, apttTargetTypes, szTargetTypes, uiPollNr, uiPeriod, ntTargets, 0)) < 0)
|
||||
return res;
|
||||
switch (res) {
|
||||
case 0:
|
||||
return pnd->last_error = NFC_SUCCESS;
|
||||
break;
|
||||
case 1:
|
||||
*pnt = ntTargets[0];
|
||||
if (pn53x_current_target_new(pnd, pnt) == NULL) {
|
||||
return pnd->last_error = NFC_ESOFT;
|
||||
}
|
||||
return res;
|
||||
break;
|
||||
case 2:
|
||||
*pnt = ntTargets[1]; // We keep the selected one
|
||||
if (pn53x_current_target_new(pnd, pnt) == NULL) {
|
||||
return pnd->last_error = NFC_ESOFT;
|
||||
}
|
||||
return res;
|
||||
break;
|
||||
default:
|
||||
return NFC_ECHIP;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
bool bInfiniteSelect = pnd->bInfiniteSelect;
|
||||
@ -1303,7 +1508,6 @@ pn53x_initiator_select_dep_target(struct nfc_device *pnd,
|
||||
case NBR_847:
|
||||
case NBR_UNDEFINED:
|
||||
return NFC_EINVARG;
|
||||
break;
|
||||
}
|
||||
|
||||
pn53x_current_target_free(pnd);
|
||||
@ -1334,7 +1538,7 @@ pn53x_initiator_transceive_bits(struct nfc_device *pnd, const uint8_t *pbtTx, co
|
||||
uint8_t abtCmd[PN53x_EXTENDED_FRAME__DATA_MAX_LEN] = { InCommunicateThru };
|
||||
|
||||
// Check if we should prepare the parity bits ourself
|
||||
if (!pnd->bPar) {
|
||||
if ((!pnd->bPar) && (szTxBits > 0)) {
|
||||
// Convert data with parity to a frame
|
||||
if ((res = pn53x_wrap_frame(pbtTx, szTxBits, pbtTxPar, abtCmd + 1)) < 0)
|
||||
return res;
|
||||
@ -1466,9 +1670,8 @@ static void __pn53x_init_timer(struct nfc_device *pnd, const uint32_t max_cycles
|
||||
|
||||
static uint32_t __pn53x_get_timer(struct nfc_device *pnd, const uint8_t last_cmd_byte)
|
||||
{
|
||||
uint8_t parity;
|
||||
uint8_t counter_hi, counter_lo;
|
||||
uint16_t counter, u16cycles;
|
||||
uint16_t counter;
|
||||
uint32_t u32cycles;
|
||||
size_t off = 0;
|
||||
if (CHIP_DATA(pnd)->type == PN533) {
|
||||
@ -1496,6 +1699,8 @@ static uint32_t __pn53x_get_timer(struct nfc_device *pnd, const uint8_t last_cmd
|
||||
// counter saturated
|
||||
u32cycles = 0xFFFFFFFF;
|
||||
} else {
|
||||
uint8_t parity;
|
||||
uint16_t u16cycles;
|
||||
u16cycles = 0xFFFF - counter;
|
||||
u32cycles = u16cycles;
|
||||
u32cycles *= (CHIP_DATA(pnd)->timer_prescaler * 2 + 1);
|
||||
@ -1733,7 +1938,7 @@ pn53x_initiator_transceive_bytes_timed(struct nfc_device *pnd, const uint8_t *pb
|
||||
if (pnd->bCrc) {
|
||||
// We've to compute CRC ourselves to know last byte actually sent
|
||||
uint8_t *pbtTxRaw;
|
||||
pbtTxRaw = (uint8_t *) malloc(szTx + 2);
|
||||
pbtTxRaw = (uint8_t *) calloc(szTx + 2, 1);
|
||||
if (!pbtTxRaw)
|
||||
return NFC_ESOFT;
|
||||
memcpy(pbtTxRaw, pbtTx, szTx);
|
||||
@ -1846,6 +2051,40 @@ static int pn53x_ISO14443A_Jewel_is_present(struct nfc_device *pnd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pn53x_ISO14443A_Barcode_is_present(struct nfc_device *pnd)
|
||||
{
|
||||
int ret;
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "target_is_present(): Ping Barcode");
|
||||
|
||||
// We turn RF field off first for a better detection rate but this doesn't work well with ASK LoGO
|
||||
if ((! CHIP_DATA(pnd)->progressive_field) && (ret = nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, false)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false)) < 0)
|
||||
return ret;
|
||||
if ((ret = nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, false)) < 0)
|
||||
return ret;
|
||||
|
||||
int failures = 0;
|
||||
while (failures < 3) {
|
||||
if ((! CHIP_DATA(pnd)->progressive_field) && (ret = nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, false)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||
uint8_t abtRxPar[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||
if (nfc_initiator_transceive_bits(pnd, NULL, 0, NULL, abtRx, sizeof(abtRx), abtRxPar) < 1) {
|
||||
failures++;
|
||||
} else {
|
||||
nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true);
|
||||
nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, true);
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
}
|
||||
nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true);
|
||||
nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, true);
|
||||
return NFC_ETGRELEASED;
|
||||
}
|
||||
|
||||
static int pn53x_ISO14443A_MFUL_is_present(struct nfc_device *pnd)
|
||||
{
|
||||
int ret;
|
||||
@ -2016,6 +2255,29 @@ static int pn53x_ISO14443B_SR_is_present(struct nfc_device *pnd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pn53x_ISO14443B_ICLASS_is_present(struct nfc_device *pnd)
|
||||
{
|
||||
int timeout = 300;
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "target_is_present(): Ping B iClass");
|
||||
pn53x_initiator_init_iclass_modulation(pnd);
|
||||
//
|
||||
// Some work to do before getting the UID...
|
||||
// send ICLASS_ACTIVATE_ALL command - will get timeout as we don't expect response
|
||||
uint8_t abtReqt[] = { 0x0a }; // iClass ACTIVATE_ALL
|
||||
uint8_t abtAnticol[11];
|
||||
if (pn53x_initiator_transceive_bytes(pnd, abtReqt, sizeof(abtReqt), NULL, 0, timeout) < 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "got expected timeout on iClass activate all");
|
||||
}
|
||||
// do select - returned anticol contains 'handle' for tag if present
|
||||
abtReqt[0] = 0x0c; // iClass SELECT
|
||||
abtAnticol[0] = 0x81; // iClass ANTICOL
|
||||
if (pn53x_initiator_transceive_bytes(pnd, abtReqt, sizeof(abtReqt), &abtAnticol[1], sizeof(abtAnticol) - 1, timeout) < 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "timeout on iClass anticol");
|
||||
return NFC_ETGRELEASED;;
|
||||
}
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
static int pn53x_ISO14443B_CT_is_present(struct nfc_device *pnd)
|
||||
{
|
||||
int ret;
|
||||
@ -2056,7 +2318,7 @@ pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt)
|
||||
}
|
||||
|
||||
// Ping target
|
||||
int ret;
|
||||
int ret = NFC_EDEVNOTSUPP;
|
||||
switch (CHIP_DATA(pnd)->current_target->nm.nmt) {
|
||||
case NMT_ISO14443A:
|
||||
if (CHIP_DATA(pnd)->current_target->nti.nai.btSak & 0x20) {
|
||||
@ -2081,6 +2343,9 @@ pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt)
|
||||
case NMT_JEWEL:
|
||||
ret = pn53x_ISO14443A_Jewel_is_present(pnd);
|
||||
break;
|
||||
case NMT_BARCODE:
|
||||
ret = pn53x_ISO14443A_Barcode_is_present(pnd);
|
||||
break;
|
||||
case NMT_ISO14443B:
|
||||
ret = pn53x_ISO14443B_4_is_present(pnd);
|
||||
break;
|
||||
@ -2093,9 +2358,8 @@ pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt)
|
||||
case NMT_ISO14443B2CT:
|
||||
ret = pn53x_ISO14443B_CT_is_present(pnd);
|
||||
break;
|
||||
default:
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "target_is_present(): card type not supported");
|
||||
ret = NFC_EDEVNOTSUPP;
|
||||
case NMT_ISO14443BICLASS:
|
||||
ret = pn53x_ISO14443B_ICLASS_is_present(pnd);
|
||||
break;
|
||||
}
|
||||
if (ret == NFC_ETGRELEASED)
|
||||
@ -2147,10 +2411,11 @@ pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const
|
||||
case NMT_ISO14443BI:
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT:
|
||||
case NMT_ISO14443BICLASS:
|
||||
case NMT_JEWEL:
|
||||
case NMT_BARCODE:
|
||||
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||
return pnd->last_error;
|
||||
break;
|
||||
}
|
||||
|
||||
// Let the PN53X be activated by the RF level detector from power down mode
|
||||
@ -2249,10 +2514,11 @@ pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const
|
||||
case NMT_ISO14443BI:
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT:
|
||||
case NMT_ISO14443BICLASS:
|
||||
case NMT_JEWEL:
|
||||
case NMT_BARCODE:
|
||||
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||
return pnd->last_error;
|
||||
break;
|
||||
}
|
||||
|
||||
bool targetActivated = false;
|
||||
@ -2397,12 +2663,15 @@ pn53x_target_receive_bytes(struct nfc_device *pnd, uint8_t *pbtRx, const size_t
|
||||
return pnd->last_error;
|
||||
}
|
||||
}
|
||||
// NO BREAK
|
||||
abtCmd[0] = TgGetInitiatorCommand;
|
||||
break;
|
||||
case NMT_JEWEL:
|
||||
case NMT_BARCODE:
|
||||
case NMT_ISO14443B:
|
||||
case NMT_ISO14443BI:
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT:
|
||||
case NMT_ISO14443BICLASS:
|
||||
case NMT_FELICA:
|
||||
abtCmd[0] = TgGetInitiatorCommand;
|
||||
break;
|
||||
@ -2502,12 +2771,15 @@ pn53x_target_send_bytes(struct nfc_device *pnd, const uint8_t *pbtTx, const size
|
||||
return pnd->last_error;
|
||||
}
|
||||
}
|
||||
// NO BREAK
|
||||
abtCmd[0] = TgResponseToInitiator;
|
||||
break;
|
||||
case NMT_JEWEL:
|
||||
case NMT_BARCODE:
|
||||
case NMT_ISO14443B:
|
||||
case NMT_ISO14443BI:
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT:
|
||||
case NMT_ISO14443BICLASS:
|
||||
case NMT_FELICA:
|
||||
abtCmd[0] = TgResponseToInitiator;
|
||||
break;
|
||||
@ -2720,6 +2992,7 @@ pn53x_InListPassiveTarget(struct nfc_device *pnd,
|
||||
}
|
||||
break;
|
||||
case PM_JEWEL_106:
|
||||
case PM_BARCODE_106:
|
||||
if (CHIP_DATA(pnd)->type == PN531) {
|
||||
// These modulations are not supported by pn531
|
||||
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||
@ -2911,7 +3184,6 @@ pn53x_InJumpForDEP(struct nfc_device *pnd,
|
||||
case NBR_UNDEFINED:
|
||||
pnd->last_error = NFC_EINVARG;
|
||||
return pnd->last_error;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pbtNFCID3i) {
|
||||
@ -3128,22 +3400,18 @@ pn53x_nm_to_pm(const nfc_modulation nm)
|
||||
switch (nm.nmt) {
|
||||
case NMT_ISO14443A:
|
||||
return PM_ISO14443A_106;
|
||||
break;
|
||||
|
||||
case NMT_ISO14443B:
|
||||
case NMT_ISO14443BICLASS:
|
||||
switch (nm.nbr) {
|
||||
case NBR_106:
|
||||
return PM_ISO14443B_106;
|
||||
break;
|
||||
case NBR_212:
|
||||
return PM_ISO14443B_212;
|
||||
break;
|
||||
case NBR_424:
|
||||
return PM_ISO14443B_424;
|
||||
break;
|
||||
case NBR_847:
|
||||
return PM_ISO14443B_847;
|
||||
break;
|
||||
case NBR_UNDEFINED:
|
||||
// Nothing to do...
|
||||
break;
|
||||
@ -3152,16 +3420,16 @@ pn53x_nm_to_pm(const nfc_modulation nm)
|
||||
|
||||
case NMT_JEWEL:
|
||||
return PM_JEWEL_106;
|
||||
break;
|
||||
|
||||
case NMT_BARCODE:
|
||||
return PM_BARCODE_106;
|
||||
|
||||
case NMT_FELICA:
|
||||
switch (nm.nbr) {
|
||||
case NBR_212:
|
||||
return PM_FELICA_212;
|
||||
break;
|
||||
case NBR_424:
|
||||
return PM_FELICA_424;
|
||||
break;
|
||||
case NBR_106:
|
||||
case NBR_847:
|
||||
case NBR_UNDEFINED:
|
||||
@ -3194,36 +3462,31 @@ pn53x_ptt_to_nm(const pn53x_target_type ptt)
|
||||
case PTT_MIFARE:
|
||||
case PTT_ISO14443_4A_106:
|
||||
return (const nfc_modulation) { .nmt = NMT_ISO14443A, .nbr = NBR_106 };
|
||||
break;
|
||||
|
||||
case PTT_ISO14443_4B_106:
|
||||
case PTT_ISO14443_4B_TCL_106:
|
||||
return (const nfc_modulation) { .nmt = NMT_ISO14443B, .nbr = NBR_106 };
|
||||
break;
|
||||
|
||||
case PTT_JEWEL_106:
|
||||
return (const nfc_modulation) { .nmt = NMT_JEWEL, .nbr = NBR_106 };
|
||||
break;
|
||||
|
||||
case PTT_FELICA_212:
|
||||
return (const nfc_modulation) { .nmt = NMT_FELICA, .nbr = NBR_212 };
|
||||
break;
|
||||
|
||||
case PTT_FELICA_424:
|
||||
return (const nfc_modulation) { .nmt = NMT_FELICA, .nbr = NBR_424 };
|
||||
break;
|
||||
|
||||
case PTT_DEP_PASSIVE_106:
|
||||
case PTT_DEP_ACTIVE_106:
|
||||
return (const nfc_modulation) { .nmt = NMT_DEP, .nbr = NBR_106 };
|
||||
break;
|
||||
|
||||
case PTT_DEP_PASSIVE_212:
|
||||
case PTT_DEP_ACTIVE_212:
|
||||
return (const nfc_modulation) { .nmt = NMT_DEP, .nbr = NBR_212 };
|
||||
break;
|
||||
|
||||
case PTT_DEP_PASSIVE_424:
|
||||
case PTT_DEP_ACTIVE_424:
|
||||
return (const nfc_modulation) { .nmt = NMT_DEP, .nbr = NBR_424 };
|
||||
break;
|
||||
}
|
||||
// We should never be here, this line silent compilation warning
|
||||
return (const nfc_modulation) { .nmt = NMT_ISO14443A, .nbr = NBR_106 };
|
||||
@ -3235,14 +3498,14 @@ pn53x_nm_to_ptt(const nfc_modulation nm)
|
||||
switch (nm.nmt) {
|
||||
case NMT_ISO14443A:
|
||||
return PTT_MIFARE;
|
||||
// return PTT_ISO14443_4A_106;
|
||||
break;
|
||||
// return PTT_ISO14443_4A_106;
|
||||
|
||||
case NMT_ISO14443B:
|
||||
case NMT_ISO14443BICLASS:
|
||||
switch (nm.nbr) {
|
||||
case NBR_106:
|
||||
return PTT_ISO14443_4B_106;
|
||||
break;
|
||||
|
||||
case NBR_UNDEFINED:
|
||||
case NBR_212:
|
||||
case NBR_424:
|
||||
@ -3254,16 +3517,15 @@ pn53x_nm_to_ptt(const nfc_modulation nm)
|
||||
|
||||
case NMT_JEWEL:
|
||||
return PTT_JEWEL_106;
|
||||
break;
|
||||
|
||||
case NMT_FELICA:
|
||||
switch (nm.nbr) {
|
||||
case NBR_212:
|
||||
return PTT_FELICA_212;
|
||||
break;
|
||||
|
||||
case NBR_424:
|
||||
return PTT_FELICA_424;
|
||||
break;
|
||||
|
||||
case NBR_UNDEFINED:
|
||||
case NBR_106:
|
||||
case NBR_847:
|
||||
@ -3275,6 +3537,7 @@ pn53x_nm_to_ptt(const nfc_modulation nm)
|
||||
case NMT_ISO14443BI:
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT:
|
||||
case NMT_BARCODE:
|
||||
case NMT_DEP:
|
||||
// Nothing to do...
|
||||
break;
|
||||
@ -3299,19 +3562,21 @@ pn53x_get_supported_modulation(nfc_device *pnd, const nfc_mode mode, const nfc_m
|
||||
}
|
||||
|
||||
int
|
||||
pn53x_get_supported_baud_rate(nfc_device *pnd, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br)
|
||||
pn53x_get_supported_baud_rate(nfc_device *pnd, const nfc_mode mode, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br)
|
||||
{
|
||||
switch (nmt) {
|
||||
case NMT_FELICA:
|
||||
*supported_br = (nfc_baud_rate *)pn53x_felica_supported_baud_rates;
|
||||
break;
|
||||
case NMT_ISO14443A:
|
||||
*supported_br = (nfc_baud_rate *)pn53x_iso14443a_supported_baud_rates;
|
||||
break;
|
||||
case NMT_ISO14443B:
|
||||
case NMT_ISO14443BI:
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT: {
|
||||
case NMT_ISO14443A: {
|
||||
if ((CHIP_DATA(pnd)->type != PN533) || (mode == N_TARGET)) {
|
||||
*supported_br = (nfc_baud_rate *)pn532_iso14443a_supported_baud_rates;
|
||||
} else {
|
||||
*supported_br = (nfc_baud_rate *)pn533_iso14443a_supported_baud_rates;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NMT_ISO14443B: {
|
||||
if ((CHIP_DATA(pnd)->type != PN533)) {
|
||||
*supported_br = (nfc_baud_rate *)pn532_iso14443b_supported_baud_rates;
|
||||
} else {
|
||||
@ -3319,9 +3584,18 @@ pn53x_get_supported_baud_rate(nfc_device *pnd, const nfc_modulation_type nmt, co
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NMT_ISO14443BI:
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT:
|
||||
case NMT_ISO14443BICLASS:
|
||||
*supported_br = (nfc_baud_rate *)pn532_iso14443b_supported_baud_rates;
|
||||
break;
|
||||
case NMT_JEWEL:
|
||||
*supported_br = (nfc_baud_rate *)pn53x_jewel_supported_baud_rates;
|
||||
break;
|
||||
case NMT_BARCODE:
|
||||
*supported_br = (nfc_baud_rate *)pn53x_barcode_supported_baud_rates;
|
||||
break;
|
||||
case NMT_DEP:
|
||||
*supported_br = (nfc_baud_rate *)pn53x_dep_supported_baud_rates;
|
||||
break;
|
||||
@ -3434,7 +3708,6 @@ pn53x_get_information_about(nfc_device *pnd, char **pbuf)
|
||||
free(*pbuf);
|
||||
return res;
|
||||
}
|
||||
|
||||
for (int i = 0; nmt[i]; i++) {
|
||||
if ((res = snprintf(buf, buflen, "%s%s (", (i == 0) ? "" : ", ", str_nfc_modulation_type(nmt[i]))) < 0) {
|
||||
free(*pbuf);
|
||||
@ -3447,7 +3720,7 @@ pn53x_get_information_about(nfc_device *pnd, char **pbuf)
|
||||
}
|
||||
buflen -= res;
|
||||
const nfc_baud_rate *nbr;
|
||||
if ((res = nfc_device_get_supported_baud_rate(pnd, nmt[i], &nbr)) < 0) {
|
||||
if ((res = nfc_device_get_supported_baud_rate_target_mode(pnd, nmt[i], &nbr)) < 0) {
|
||||
free(*pbuf);
|
||||
return res;
|
||||
}
|
||||
@ -3576,6 +3849,9 @@ pn53x_data_new(struct nfc_device *pnd, const struct pn53x_io *io)
|
||||
|
||||
CHIP_DATA(pnd)->supported_modulation_as_target = NULL;
|
||||
|
||||
// Set default progressive field flag
|
||||
CHIP_DATA(pnd)->progressive_field = false;
|
||||
|
||||
return pnd->chip_data;
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||
* See AUTHORS file for a more comprehensive list of contributors.
|
||||
* Additional contributors of this file:
|
||||
* Copyright (C) 2020 Adam Laurie
|
||||
*
|
||||
* 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
|
||||
@ -210,6 +211,7 @@ struct pn53x_data {
|
||||
/** Supported modulation type */
|
||||
nfc_modulation_type *supported_modulation_as_initiator;
|
||||
nfc_modulation_type *supported_modulation_as_target;
|
||||
bool progressive_field;
|
||||
};
|
||||
|
||||
#define CHIP_DATA(pnd) ((struct pn53x_data*)(pnd->chip_data))
|
||||
@ -231,6 +233,8 @@ typedef enum {
|
||||
PM_ISO14443B_106 = 0x03,
|
||||
/** Jewel Topaz (Innovision Research & Development) (Not supported by PN531) */
|
||||
PM_JEWEL_106 = 0x04,
|
||||
/** Thinfilm NFC Barcode (Not supported by PN531) */
|
||||
PM_BARCODE_106 = 0x05,
|
||||
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531 nor PN532) */
|
||||
PM_ISO14443B_212 = 0x06,
|
||||
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531 nor PN532) */
|
||||
@ -319,6 +323,7 @@ int pn53x_idle(struct nfc_device *pnd);
|
||||
|
||||
// NFC device as Initiator functions
|
||||
int pn53x_initiator_init(struct nfc_device *pnd);
|
||||
void pn53x_initiator_init_iclass_modulation(struct nfc_device *pnd);
|
||||
int pn532_initiator_init_secure_element(struct nfc_device *pnd);
|
||||
int pn53x_initiator_select_passive_target(struct nfc_device *pnd,
|
||||
const nfc_modulation nm,
|
||||
@ -392,7 +397,7 @@ int pn53x_check_ack_frame(struct nfc_device *pnd, const uint8_t *pbtRxFrame,
|
||||
int pn53x_check_error_frame(struct nfc_device *pnd, const uint8_t *pbtRxFrame, const size_t szRxFrameLen);
|
||||
int pn53x_build_frame(uint8_t *pbtFrame, size_t *pszFrame, const uint8_t *pbtData, const size_t szData);
|
||||
int pn53x_get_supported_modulation(nfc_device *pnd, const nfc_mode mode, const nfc_modulation_type **const supported_mt);
|
||||
int pn53x_get_supported_baud_rate(nfc_device *pnd, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br);
|
||||
int pn53x_get_supported_baud_rate(nfc_device *pnd, const nfc_mode mode, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br);
|
||||
int pn53x_get_information_about(nfc_device *pnd, char **pbuf);
|
||||
|
||||
void *pn53x_data_new(struct nfc_device *pnd, const struct pn53x_io *io);
|
||||
|
||||
169
libnfc/conf.c
169
libnfc/conf.c
@ -33,9 +33,9 @@
|
||||
#ifdef CONFFILES
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <regex.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
@ -56,30 +56,129 @@
|
||||
#define LIBNFC_CONFFILE LIBNFC_SYSCONFDIR"/libnfc.conf"
|
||||
#define LIBNFC_DEVICECONFDIR LIBNFC_SYSCONFDIR"/devices.d"
|
||||
|
||||
static bool
|
||||
conf_parse_file(const char *filename, void (*conf_keyvalue)(void *data, const char *key, const char *value), void *data)
|
||||
static int
|
||||
escaped_value(const char line[BUFSIZ], int i, char **value)
|
||||
{
|
||||
if (line[i] != '"')
|
||||
goto FAIL;
|
||||
i++;
|
||||
if (line[i] == 0 || line[i] == '\n')
|
||||
goto FAIL;
|
||||
int c = 0;
|
||||
while (line[i] && line[i] != '"') {
|
||||
i++;
|
||||
c++;
|
||||
}
|
||||
if (line[i] != '"')
|
||||
goto FAIL;
|
||||
*value = malloc(c + 1);
|
||||
if (!*value)
|
||||
goto FAIL;
|
||||
memset(*value, 0, c + 1);
|
||||
memcpy(*value, &line[i - c], c);
|
||||
i++;
|
||||
while (line[i] && isspace(line[i]))
|
||||
i++;
|
||||
if (line[i] != 0 && line[i] != '\n')
|
||||
goto FAIL;
|
||||
return 0;
|
||||
|
||||
FAIL:
|
||||
free(*value);
|
||||
*value = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
non_escaped_value(const char line[BUFSIZ], int i, char **value)
|
||||
{
|
||||
int c = 0;
|
||||
while (line[i] && !isspace(line[i])) {
|
||||
i++;
|
||||
c++;
|
||||
}
|
||||
*value = malloc(c + 1);
|
||||
if (!*value)
|
||||
goto FAIL;
|
||||
memset(*value, 0, c + 1);
|
||||
memcpy(*value, &line[i - c], c);
|
||||
i++;
|
||||
while (line[i] && isspace(line[i]))
|
||||
i++;
|
||||
if (line[i] != 0)
|
||||
goto FAIL;
|
||||
return 0;
|
||||
|
||||
FAIL:
|
||||
free(*value);
|
||||
*value = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_line(const char line[BUFSIZ], char **key, char **value)
|
||||
{
|
||||
*key = NULL;
|
||||
*value = NULL;
|
||||
int i = 0;
|
||||
int c = 0;
|
||||
|
||||
// optional initial spaces
|
||||
while (isspace(line[i]))
|
||||
i++;
|
||||
if (line[i] == 0 || line[i] == '\n')
|
||||
return -1;
|
||||
|
||||
// key
|
||||
while (isalnum(line[i]) || line[i] == '_' || line[i] == '.') {
|
||||
i++;
|
||||
c++;
|
||||
}
|
||||
if (c == 0 || line[i] == 0 || line[i] == '\n') // key is empty
|
||||
return -1;
|
||||
*key = malloc(c + 1);
|
||||
if (!*key)
|
||||
return -1;
|
||||
memset(*key, 0, c + 1);
|
||||
memcpy(*key, &line[i - c], c);
|
||||
|
||||
// space before '='
|
||||
while (isspace(line[i]))
|
||||
i++;
|
||||
if (line[i] != '=')
|
||||
return -1;
|
||||
i++;
|
||||
if (line[i] == 0 || line[i] == '\n')
|
||||
return -1;
|
||||
// space after '='
|
||||
while (isspace(line[i]))
|
||||
i++;
|
||||
if (line[i] == 0 || line[i] == '\n')
|
||||
return -1;
|
||||
if (escaped_value(line, i, value) == 0)
|
||||
return 0;
|
||||
else if (non_escaped_value(line, i, value) == 0)
|
||||
return 0;
|
||||
|
||||
// Extracting key or value failed
|
||||
free(*key);
|
||||
*key = NULL;
|
||||
free(*value);
|
||||
*value = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
conf_parse_file(const char *filename,
|
||||
void (*conf_keyvalue)(void *data, const char *key, const char *value),
|
||||
void *data)
|
||||
{
|
||||
FILE *f = fopen(filename, "r");
|
||||
if (!f) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "Unable to open file: %s", filename);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
char line[BUFSIZ];
|
||||
const char *str_regex = "^[[:space:]]*([[:alnum:]_.]+)[[:space:]]*=[[:space:]]*(\"(.+)\"|([^[:space:]]+))[[:space:]]*$";
|
||||
regex_t preg;
|
||||
if (regcomp(&preg, str_regex, REG_EXTENDED | REG_NOTEOL) != 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Regular expression used for configuration file parsing is not valid.");
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
size_t nmatch = preg.re_nsub + 1;
|
||||
regmatch_t *pmatch = malloc(sizeof(*pmatch) * nmatch);
|
||||
if (!pmatch) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Not enough memory: malloc failed.");
|
||||
regfree(&preg);
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
int lineno = 0;
|
||||
while (fgets(line, BUFSIZ, f) != NULL) {
|
||||
@ -89,30 +188,22 @@ conf_parse_file(const char *filename, void (*conf_keyvalue)(void *data, const ch
|
||||
case '\n':
|
||||
break;
|
||||
default: {
|
||||
int match;
|
||||
if ((match = regexec(&preg, line, nmatch, pmatch, 0)) == 0) {
|
||||
const size_t key_size = pmatch[1].rm_eo - pmatch[1].rm_so;
|
||||
const off_t value_pmatch = pmatch[3].rm_eo != -1 ? 3 : 4;
|
||||
const size_t value_size = pmatch[value_pmatch].rm_eo - pmatch[value_pmatch].rm_so;
|
||||
char key[key_size + 1];
|
||||
char value[value_size + 1];
|
||||
strncpy(key, line + (pmatch[1].rm_so), key_size);
|
||||
key[key_size] = '\0';
|
||||
strncpy(value, line + (pmatch[value_pmatch].rm_so), value_size);
|
||||
value[value_size] = '\0';
|
||||
char *key;
|
||||
char *value;
|
||||
if (parse_line(line, &key, &value) == 0) {
|
||||
conf_keyvalue(data, key, value);
|
||||
free(key);
|
||||
free(value);
|
||||
} else {
|
||||
free(key);
|
||||
free(value);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Parse error on line #%d: %s", lineno, line);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(pmatch);
|
||||
regfree(&preg);
|
||||
fclose(f);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -177,14 +268,8 @@ conf_devices_load(const char *dirname, nfc_context *context)
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Unable to open directory: %s", dirname);
|
||||
} else {
|
||||
struct dirent *de;
|
||||
#ifdef WIN32
|
||||
while ((de = readdir(d)) != NULL) {
|
||||
#else
|
||||
struct dirent entry;
|
||||
struct dirent *result;
|
||||
while ((readdir_r(d, &entry, &result) == 0) && (result != NULL)) {
|
||||
de = &entry;
|
||||
#endif
|
||||
// FIXME add a way to sort devices
|
||||
if (de->d_name[0] != '.') {
|
||||
const size_t filename_len = strlen(de->d_name);
|
||||
const size_t extension_len = strlen(".conf");
|
||||
|
||||
@ -7,6 +7,10 @@ libnfcdrivers_la_SOURCES =
|
||||
libnfcdrivers_la_CFLAGS = @DRIVERS_CFLAGS@ -I$(top_srcdir)/libnfc -I$(top_srcdir)/libnfc/buses
|
||||
libnfcdrivers_la_LIBADD =
|
||||
|
||||
if DRIVER_PCSC_ENABLED
|
||||
libnfcdrivers_la_SOURCES += pcsc.c pcsc.h
|
||||
endif
|
||||
|
||||
if DRIVER_ACR122_PCSC_ENABLED
|
||||
libnfcdrivers_la_SOURCES += acr122_pcsc.c acr122_pcsc.h
|
||||
endif
|
||||
@ -39,6 +43,11 @@ if DRIVER_PN532_I2C_ENABLED
|
||||
libnfcdrivers_la_SOURCES += pn532_i2c.c pn532_i2c.h
|
||||
endif
|
||||
|
||||
if DRIVER_PN71XX_ENABLED
|
||||
libnfcdrivers_la_LIBADD += @LIBNFC_NCI_LIBS@
|
||||
libnfcdrivers_la_SOURCES += pn71xx.c pn71xx.h
|
||||
endif
|
||||
|
||||
if PCSC_ENABLED
|
||||
libnfcdrivers_la_CFLAGS += @libpcsclite_CFLAGS@
|
||||
libnfcdrivers_la_LIBADD += @libpcsclite_LIBS@
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
# define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE SCARD_CTL_CODE(3500)
|
||||
#elif defined(__APPLE__)
|
||||
# define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE (((0x31) << 16) | ((3500) << 2))
|
||||
#elif defined (__FreeBSD__) || defined (__OpenBSD__)
|
||||
#elif defined (__FreeBSD__) || defined (__OpenBSD__) || defined (__NetBSD__)
|
||||
# define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE (((0x31) << 16) | ((3500) << 2))
|
||||
#elif defined (__linux__)
|
||||
# include <reader.h>
|
||||
@ -93,7 +93,7 @@ const struct pn53x_io acr122_pcsc_io;
|
||||
// Prototypes
|
||||
char *acr122_pcsc_firmware(nfc_device *pnd);
|
||||
|
||||
const char *supported_devices[] = {
|
||||
static const char *supported_devices[] = {
|
||||
"ACS ACR122", // ACR122U & Touchatag, last version
|
||||
"ACS ACR 38U-CCID", // Touchatag, early version
|
||||
"ACS ACR38U-CCID", // Touchatag, early version, under MacOSX
|
||||
@ -400,15 +400,14 @@ acr122_pcsc_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szData, int
|
||||
{
|
||||
// FIXME: timeout is not handled
|
||||
(void) timeout;
|
||||
|
||||
int len;
|
||||
uint8_t abtRxCmd[5] = { 0xFF, 0xC0, 0x00, 0x00 };
|
||||
|
||||
if (DRIVER_DATA(pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_T0) {
|
||||
/*
|
||||
* Retrieve the PN532 response.
|
||||
*/
|
||||
DWORD dwRxLen = sizeof(DRIVER_DATA(pnd)->abtRx);
|
||||
uint8_t abtRxCmd[5] = { 0xFF, 0xC0, 0x00, 0x00 };
|
||||
abtRxCmd[4] = DRIVER_DATA(pnd)->abtRx[1];
|
||||
if (SCardTransmit(DRIVER_DATA(pnd)->hCard, &(DRIVER_DATA(pnd)->ioCard), abtRxCmd, sizeof(abtRxCmd), NULL, DRIVER_DATA(pnd)->abtRx, &dwRxLen) != SCARD_S_SUCCESS) {
|
||||
pnd->last_error = NFC_EIO;
|
||||
|
||||
@ -60,7 +60,9 @@ Thanks to d18c7db and Okko for example code
|
||||
#include <sys/select.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <nfc/nfc.h>
|
||||
|
||||
#include "nfc-internal.h"
|
||||
@ -262,6 +264,7 @@ struct acr122_usb_supported_device {
|
||||
const struct acr122_usb_supported_device acr122_usb_supported_devices[] = {
|
||||
{ 0x072F, 0x2200, "ACS ACR122" },
|
||||
{ 0x072F, 0x90CC, "Touchatag" },
|
||||
{ 0x072F, 0x2214, "ACS ACR1222" },
|
||||
};
|
||||
|
||||
// Find transfer endpoints for bulk transfers
|
||||
@ -330,7 +333,10 @@ acr122_usb_scan(const nfc_context *context, nfc_connstring connstrings[], const
|
||||
// acr122_usb_get_usb_device_name (dev, udev, pnddDevices[device_found].acDevice, sizeof (pnddDevices[device_found].acDevice));
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "device found: Bus %s Device %s Name %s", bus->dirname, dev->filename, acr122_usb_supported_devices[n].name);
|
||||
usb_close(udev);
|
||||
snprintf(connstrings[device_found], sizeof(nfc_connstring), "%s:%s:%s", ACR122_USB_DRIVER_NAME, bus->dirname, dev->filename);
|
||||
if (snprintf(connstrings[device_found], sizeof(nfc_connstring), "%s:%s:%s", ACR122_USB_DRIVER_NAME, bus->dirname, dev->filename) >= (int)sizeof(nfc_connstring)) {
|
||||
// truncation occurred, skipping that one
|
||||
continue;
|
||||
}
|
||||
device_found++;
|
||||
// Test if we reach the maximum "wanted" devices
|
||||
if (device_found == connstrings_len) {
|
||||
@ -426,12 +432,15 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring)
|
||||
goto free_mem;
|
||||
}
|
||||
|
||||
res = usb_set_altinterface(data.pudh, 0);
|
||||
if (res < 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to set alternate setting on USB interface (%s)", _usb_strerror(res));
|
||||
usb_close(data.pudh);
|
||||
// we failed to use the specified device
|
||||
goto free_mem;
|
||||
// Check if there are more than 0 alternative interfaces and claim the first one
|
||||
if (dev->config->interface->altsetting->bAlternateSetting > 0) {
|
||||
res = usb_set_altinterface(data.pudh, 0);
|
||||
if (res < 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to set alternate setting on USB interface (%s)", _usb_strerror(res));
|
||||
usb_close(data.pudh);
|
||||
// we failed to use the specified device
|
||||
goto free_mem;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate memory for the device info and specification, fill it and return the info
|
||||
@ -589,7 +598,7 @@ read:
|
||||
if (timeout == USB_INFINITE_TIMEOUT) {
|
||||
usb_timeout = USB_TIMEOUT_PER_PASS;
|
||||
} else {
|
||||
// A user-provided timeout is set, we have to cut it in multiple chunk to be able to keep an nfc_abort_command() mecanism
|
||||
// A user-provided timeout is set, we have to cut it in multiple chunk to be able to keep an nfc_abort_command() mechanism
|
||||
remaining_time -= USB_TIMEOUT_PER_PASS;
|
||||
if (remaining_time <= 0) {
|
||||
pnd->last_error = NFC_ETIMEOUT;
|
||||
@ -603,6 +612,7 @@ read:
|
||||
|
||||
uint8_t attempted_response = RDR_to_PC_DataBlock;
|
||||
size_t len;
|
||||
int error, status;
|
||||
|
||||
if (res == NFC_ETIMEOUT) {
|
||||
if (DRIVER_DATA(pnd)->abort_flag) {
|
||||
@ -614,7 +624,7 @@ read:
|
||||
goto read;
|
||||
}
|
||||
}
|
||||
if (res < 12) {
|
||||
if (res < 10) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Invalid RDR_to_PC_DataBlock frame");
|
||||
// try to interrupt current device state
|
||||
acr122_usb_ack(pnd);
|
||||
@ -629,6 +639,16 @@ read:
|
||||
offset++;
|
||||
|
||||
len = abtRxBuf[offset++];
|
||||
status = abtRxBuf[7];
|
||||
error = abtRxBuf[8];
|
||||
if (len == 0 && error == 0xFE) { // ICC_MUTE; XXX check for more errors
|
||||
// Do not check status; my ACR122U seemingly has status=0 in this case,
|
||||
// even though the spec says it should have had bmCommandStatus=1
|
||||
// and bmICCStatus=1.
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "Command timed out");
|
||||
pnd->last_error = NFC_ETIMEOUT;
|
||||
return pnd->last_error;
|
||||
}
|
||||
if (!((len > 1) && (abtRxBuf[10] == 0xd5))) { // In case we didn't get an immediate answer:
|
||||
if (len != 2) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Wrong reply");
|
||||
@ -657,7 +677,7 @@ read:
|
||||
goto read; // FIXME May cause some trouble on Touchatag, right ?
|
||||
}
|
||||
}
|
||||
if (res < 12) {
|
||||
if (res < 10) {
|
||||
// try to interrupt current device state
|
||||
acr122_usb_ack(pnd);
|
||||
pnd->last_error = NFC_EIO;
|
||||
|
||||
@ -422,7 +422,7 @@ acr122s_scan(const nfc_context *context, nfc_connstring connstrings[], const siz
|
||||
|
||||
while ((acPort = acPorts[iDevice++])) {
|
||||
sp = uart_open(acPort);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Trying to find ACR122S device on serial port: %s at %d bauds.", acPort, ACR122S_DEFAULT_SPEED);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Trying to find ACR122S device on serial port: %s at %d baud.", acPort, ACR122S_DEFAULT_SPEED);
|
||||
|
||||
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
|
||||
// We need to flush input to be sure first reply does not comes from older byte transceive
|
||||
@ -527,7 +527,7 @@ acr122s_close(nfc_device *pnd)
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
|
||||
#ifndef WIN32
|
||||
// Release file descriptors used for abort mecanism
|
||||
// Release file descriptors used for abort mechanism
|
||||
close(DRIVER_DATA(pnd)->abort_fds[0]);
|
||||
close(DRIVER_DATA(pnd)->abort_fds[1]);
|
||||
#endif
|
||||
@ -562,7 +562,7 @@ acr122s_open(const nfc_context *context, const nfc_connstring connstring)
|
||||
}
|
||||
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
|
||||
"Attempt to connect to: %s at %d bauds.", ndd.port, ndd.speed);
|
||||
"Attempt to connect to: %s at %d baud.", ndd.port, ndd.speed);
|
||||
|
||||
sp = uart_open(ndd.port);
|
||||
if (sp == INVALID_SERIAL_PORT) {
|
||||
|
||||
@ -91,7 +91,6 @@ struct arygon_data {
|
||||
|
||||
// ARYGON frames
|
||||
static const uint8_t arygon_error_none[] = "FF000000\x0d\x0a";
|
||||
static const uint8_t arygon_error_incomplete_command[] = "FF0C0000\x0d\x0a";
|
||||
static const uint8_t arygon_error_unknown_mode[] = "FF060000\x0d\x0a";
|
||||
|
||||
// Prototypes
|
||||
@ -109,7 +108,7 @@ arygon_scan(const nfc_context *context, nfc_connstring connstrings[], const size
|
||||
|
||||
while ((acPort = acPorts[iDevice++])) {
|
||||
sp = uart_open(acPort);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Trying to find ARYGON device on serial port: %s at %d bauds.", acPort, ARYGON_DEFAULT_SPEED);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Trying to find ARYGON device on serial port: %s at %d baud.", acPort, ARYGON_DEFAULT_SPEED);
|
||||
|
||||
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
|
||||
// We need to flush input to be sure first reply does not comes from older byte transceive
|
||||
@ -159,7 +158,7 @@ arygon_scan(const nfc_context *context, nfc_connstring connstrings[], const size
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
// pipe-based abort mecanism
|
||||
// pipe-based abort mechanism
|
||||
if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
@ -212,7 +211,7 @@ arygon_close_step2(nfc_device *pnd)
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
|
||||
#ifndef WIN32
|
||||
// Release file descriptors used for abort mecanism
|
||||
// Release file descriptors used for abort mechanism
|
||||
close(DRIVER_DATA(pnd)->iAbortFds[0]);
|
||||
close(DRIVER_DATA(pnd)->iAbortFds[1]);
|
||||
#endif
|
||||
@ -253,7 +252,7 @@ arygon_open(const nfc_context *context, const nfc_connstring connstring)
|
||||
serial_port sp;
|
||||
nfc_device *pnd = NULL;
|
||||
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Attempt to open: %s at %d bauds.", ndd.port, ndd.speed);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Attempt to open: %s at %d baud.", ndd.port, ndd.speed);
|
||||
sp = uart_open(ndd.port);
|
||||
|
||||
if (sp == INVALID_SERIAL_PORT)
|
||||
@ -305,7 +304,7 @@ arygon_open(const nfc_context *context, const nfc_connstring connstring)
|
||||
pnd->driver = &arygon_driver;
|
||||
|
||||
#ifndef WIN32
|
||||
// pipe-based abort mecanism
|
||||
// pipe-based abort mechanism
|
||||
if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
|
||||
1080
libnfc/drivers/pcsc.c
Normal file
1080
libnfc/drivers/pcsc.c
Normal file
File diff suppressed because it is too large
Load Diff
35
libnfc/drivers/pcsc.h
Normal file
35
libnfc/drivers/pcsc.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*-
|
||||
* Free/Libre Near Field Communication (NFC) library
|
||||
*
|
||||
* Libnfc historical contributors:
|
||||
* Copyright (C) 2019 Frank Morgner
|
||||
* 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 pcsc.h
|
||||
* @brief Driver for non-ACR122 devices (behind PC/SC daemon)
|
||||
*/
|
||||
|
||||
#ifndef __NFC_DRIVER_PCSC_H__
|
||||
#define __NFC_DRIVER_PCSC_H__
|
||||
|
||||
#include <nfc/nfc-types.h>
|
||||
|
||||
extern const struct nfc_driver pcsc_driver;
|
||||
|
||||
#endif // ! __NFC_DRIVER_PCSC_H__
|
||||
@ -59,6 +59,13 @@
|
||||
// I2C address of the PN532 chip.
|
||||
#define PN532_I2C_ADDR 0x24
|
||||
|
||||
/*
|
||||
* When sending lots of data, the pn532 occasionally fails to respond in time.
|
||||
* Since it happens so rarely, lets try to fix it by re-sending the data. This
|
||||
* define allows for fine tuning the number of retries.
|
||||
*/
|
||||
#define PN532_SEND_RETRIES 3
|
||||
|
||||
// Internal data structs
|
||||
const struct pn53x_io pn532_i2c_io;
|
||||
|
||||
@ -67,13 +74,9 @@ struct pn532_i2c_data {
|
||||
volatile bool abort_flag;
|
||||
};
|
||||
|
||||
/* Delay for the loop waiting for READY frame (in ms) */
|
||||
#define PN532_RDY_LOOP_DELAY 90
|
||||
|
||||
const struct timespec rdyDelay = {
|
||||
.tv_sec = 0,
|
||||
.tv_nsec = PN532_RDY_LOOP_DELAY * 1000 * 1000
|
||||
};
|
||||
/* preamble and start bytes, see pn532-internal.h for details */
|
||||
const uint8_t pn53x_preamble_and_start[] = { 0x00, 0x00, 0xff };
|
||||
#define PN53X_PREAMBLE_AND_START_LEN (sizeof(pn53x_preamble_and_start) / sizeof(pn53x_preamble_and_start[0]))
|
||||
|
||||
/* Private Functions Prototypes */
|
||||
|
||||
@ -96,6 +99,70 @@ static size_t pn532_i2c_scan(const nfc_context *context, nfc_connstring connstri
|
||||
|
||||
#define DRIVER_DATA(pnd) ((struct pn532_i2c_data*)(pnd->driver_data))
|
||||
|
||||
/*
|
||||
* Bus free time (in ms) between a STOP condition and START condition. See
|
||||
* tBuf in the PN532 data sheet, section 12.25: Timing for the I2C interface,
|
||||
* table 320. I2C timing specification, page 211, rev. 3.2 - 2007-12-07.
|
||||
*/
|
||||
#define PN532_BUS_FREE_TIME 5
|
||||
static struct timespec __transaction_stop;
|
||||
|
||||
/**
|
||||
* @brief Wrapper around i2c_read to ensure proper timing by respecting the
|
||||
* minimal free bus time between a STOP condition and a START condition.
|
||||
*
|
||||
* @note This is not thread safe, but since libnfc is single threaded
|
||||
* this should be okay.
|
||||
*
|
||||
* @param id I2C device
|
||||
* @param buf pointer on buffer used to store data
|
||||
* @param len length of the buffer
|
||||
* @return length (in bytes) of read data, or driver error code (negative value)
|
||||
*/
|
||||
static ssize_t pn532_i2c_read(const i2c_device id,
|
||||
uint8_t *buf, const size_t len)
|
||||
{
|
||||
struct timespec transaction_start, bus_free_time = { 0, 0 };
|
||||
ssize_t ret;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &transaction_start);
|
||||
bus_free_time.tv_nsec = (PN532_BUS_FREE_TIME * 1000 * 1000) -
|
||||
(transaction_start.tv_nsec - __transaction_stop.tv_nsec);
|
||||
nanosleep(&bus_free_time, NULL);
|
||||
|
||||
ret = i2c_read(id, buf, len);
|
||||
clock_gettime(CLOCK_MONOTONIC, &__transaction_stop);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wrapper around i2c_write to ensure proper timing by respecting the
|
||||
* minimal free bus time between a STOP condition and a START condition.
|
||||
*
|
||||
* @note This is not thread safe, but since libnfc is single threaded
|
||||
* this should be okay.
|
||||
*
|
||||
* @param id I2C device
|
||||
* @param buf pointer on buffer containing data
|
||||
* @param len length of the buffer
|
||||
* @return NFC_SUCCESS on success, otherwise driver error code
|
||||
*/
|
||||
static ssize_t pn532_i2c_write(const i2c_device id,
|
||||
const uint8_t *buf, const size_t len)
|
||||
{
|
||||
struct timespec transaction_start, bus_free_time = { 0, 0 };
|
||||
ssize_t ret;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &transaction_start);
|
||||
bus_free_time.tv_nsec = (PN532_BUS_FREE_TIME * 1000 * 1000) -
|
||||
(transaction_start.tv_nsec - __transaction_stop.tv_nsec);
|
||||
nanosleep(&bus_free_time, NULL);
|
||||
|
||||
ret = i2c_write(id, buf, len);
|
||||
clock_gettime(CLOCK_MONOTONIC, &__transaction_stop);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Scan all available I2C buses to find PN532 devices.
|
||||
*
|
||||
@ -308,6 +375,7 @@ static int
|
||||
pn532_i2c_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout)
|
||||
{
|
||||
int res = 0;
|
||||
uint8_t retries;
|
||||
|
||||
// Discard any existing data ?
|
||||
|
||||
@ -334,15 +402,22 @@ pn532_i2c_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int
|
||||
break;
|
||||
};
|
||||
|
||||
uint8_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||
uint8_t abtFrame[PN532_BUFFER_LEN];
|
||||
size_t szFrame = 0;
|
||||
|
||||
memcpy(abtFrame, pn53x_preamble_and_start, PN53X_PREAMBLE_AND_START_LEN); // Every packet must start with the preamble and start bytes.
|
||||
if ((res = pn53x_build_frame(abtFrame, &szFrame, pbtData, szData)) < 0) {
|
||||
pnd->last_error = res;
|
||||
return pnd->last_error;
|
||||
}
|
||||
|
||||
res = i2c_write(DRIVER_DATA(pnd)->dev, abtFrame, szFrame);
|
||||
for (retries = PN532_SEND_RETRIES; retries > 0; retries--) {
|
||||
res = pn532_i2c_write(DRIVER_DATA(pnd)->dev, abtFrame, szFrame);
|
||||
if (res >= 0)
|
||||
break;
|
||||
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Failed to transmit data. Retries left: %d.", retries - 1);
|
||||
}
|
||||
|
||||
if (res < 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
|
||||
@ -400,10 +475,7 @@ pn532_i2c_wait_rdyframe(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLe
|
||||
}
|
||||
|
||||
do {
|
||||
// Wait a little bit before reading
|
||||
nanosleep(&rdyDelay, (struct timespec *) NULL);
|
||||
|
||||
int recCount = i2c_read(DRIVER_DATA(pnd)->dev, i2cRx, szDataLen + 1);
|
||||
int recCount = pn532_i2c_read(DRIVER_DATA(pnd)->dev, i2cRx, szDataLen + 1);
|
||||
|
||||
if (DRIVER_DATA(pnd)->abort_flag) {
|
||||
// Reset abort flag
|
||||
@ -477,9 +549,7 @@ pn532_i2c_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, int
|
||||
goto error;
|
||||
}
|
||||
|
||||
const uint8_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
|
||||
|
||||
if (0 != (memcmp(frameBuf, pn53x_preamble, 3))) {
|
||||
if (0 != (memcmp(frameBuf, pn53x_preamble_and_start, PN53X_PREAMBLE_AND_START_LEN))) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
|
||||
pnd->last_error = NFC_EIO;
|
||||
goto error;
|
||||
@ -572,7 +642,7 @@ error:
|
||||
int
|
||||
pn532_i2c_ack(nfc_device *pnd)
|
||||
{
|
||||
return i2c_write(DRIVER_DATA(pnd)->dev, pn53x_ack_frame, sizeof(pn53x_ack_frame));
|
||||
return pn532_i2c_write(DRIVER_DATA(pnd)->dev, pn53x_ack_frame, sizeof(pn53x_ack_frame));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -433,7 +433,7 @@ pn532_spi_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, int
|
||||
goto error;
|
||||
}
|
||||
|
||||
pnd->last_error = spi_send_receive(DRIVER_DATA(pnd)->port, &pn532_spi_cmd_dataread, 1, abtRxBuf , 4, true);
|
||||
pnd->last_error = spi_send_receive(DRIVER_DATA(pnd)->port, &pn532_spi_cmd_dataread, 1, abtRxBuf, 4, true);
|
||||
|
||||
if (pnd->last_error < 0) {
|
||||
goto error;
|
||||
|
||||
@ -82,7 +82,7 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
|
||||
|
||||
while ((acPort = acPorts[iDevice++])) {
|
||||
sp = uart_open(acPort);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Trying to find PN532 device on serial port: %s at %d bauds.", acPort, PN532_UART_DEFAULT_SPEED);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Trying to find PN532 device on serial port: %s at %d baud.", acPort, PN532_UART_DEFAULT_SPEED);
|
||||
|
||||
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
|
||||
// We need to flush input to be sure first reply does not comes from older byte transceive
|
||||
@ -136,7 +136,7 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
|
||||
CHIP_DATA(pnd)->power_mode = LOWVBAT;
|
||||
|
||||
#ifndef WIN32
|
||||
// pipe-based abort mecanism
|
||||
// pipe-based abort mechanism
|
||||
if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
@ -191,7 +191,7 @@ pn532_uart_close(nfc_device *pnd)
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
|
||||
#ifndef WIN32
|
||||
// Release file descriptors used for abort mecanism
|
||||
// Release file descriptors used for abort mechanism
|
||||
close(DRIVER_DATA(pnd)->iAbortFds[0]);
|
||||
close(DRIVER_DATA(pnd)->iAbortFds[1]);
|
||||
#endif
|
||||
@ -225,7 +225,7 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring)
|
||||
serial_port sp;
|
||||
nfc_device *pnd = NULL;
|
||||
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Attempt to open: %s at %d bauds.", ndd.port, ndd.speed);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Attempt to open: %s at %d baud.", ndd.port, ndd.speed);
|
||||
sp = uart_open(ndd.port);
|
||||
|
||||
if (sp == INVALID_SERIAL_PORT)
|
||||
@ -277,7 +277,7 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring)
|
||||
pnd->driver = &pn532_uart_driver;
|
||||
|
||||
#ifndef WIN32
|
||||
// pipe-based abort mecanism
|
||||
// pipe-based abort mechanism
|
||||
if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* 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) 2010-2017 Philippe Teuwen
|
||||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||
* See AUTHORS file for a more comprehensive list of contributors.
|
||||
* Additional contributors of this file:
|
||||
@ -43,7 +43,9 @@ Thanks to d18c7db and Okko for example code
|
||||
#include <sys/select.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <nfc/nfc.h>
|
||||
|
||||
#include "nfc-internal.h"
|
||||
@ -60,6 +62,8 @@ Thanks to d18c7db and Okko for example code
|
||||
|
||||
#define DRIVER_DATA(pnd) ((struct pn53x_usb_data*)(pnd->driver_data))
|
||||
|
||||
const nfc_modulation_type no_target_support[] = {0};
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN,
|
||||
NXP_PN531,
|
||||
@ -67,6 +71,7 @@ typedef enum {
|
||||
NXP_PN533,
|
||||
ASK_LOGO,
|
||||
SCM_SCL3711,
|
||||
SCM_SCL3712,
|
||||
SONY_RCS360
|
||||
} pn53x_usb_model;
|
||||
|
||||
@ -78,6 +83,7 @@ struct pn53x_usb_data {
|
||||
uint32_t uiEndPointOut;
|
||||
uint32_t uiMaxPacketSize;
|
||||
volatile bool abort_flag;
|
||||
bool possibly_corrupted_usbdesc;
|
||||
};
|
||||
|
||||
// Internal io struct
|
||||
@ -121,17 +127,105 @@ struct pn53x_usb_supported_device {
|
||||
uint16_t product_id;
|
||||
pn53x_usb_model model;
|
||||
const char *name;
|
||||
/* hardcoded known values for buggy hardware whose configuration vanishes */
|
||||
uint32_t uiEndPointIn;
|
||||
uint32_t uiEndPointOut;
|
||||
uint32_t uiMaxPacketSize;
|
||||
};
|
||||
|
||||
const struct pn53x_usb_supported_device pn53x_usb_supported_devices[] = {
|
||||
{ 0x04CC, 0x0531, NXP_PN531, "Philips / PN531" },
|
||||
{ 0x04CC, 0x2533, NXP_PN533, "NXP / PN533" },
|
||||
{ 0x04E6, 0x5591, SCM_SCL3711, "SCM Micro / SCL3711-NFC&RW" },
|
||||
{ 0x054c, 0x0193, SONY_PN531, "Sony / PN531" },
|
||||
{ 0x1FD3, 0x0608, ASK_LOGO, "ASK / LoGO" },
|
||||
{ 0x054C, 0x02E1, SONY_RCS360, "Sony / FeliCa S360 [PaSoRi]" }
|
||||
{ 0x04CC, 0x0531, NXP_PN531, "Philips / PN531", 0x84, 0x04, 0x40 },
|
||||
{ 0x04CC, 0x2533, NXP_PN533, "NXP / PN533", 0x84, 0x04, 0x40 },
|
||||
{ 0x04E6, 0x5591, SCM_SCL3711, "SCM Micro / SCL3711-NFC&RW", 0x84, 0x04, 0x40 },
|
||||
{ 0x04E6, 0x5594, SCM_SCL3712, "SCM Micro / SCL3712-NFC&RW", 0, 0, 0 }, // to check on real device
|
||||
{ 0x054c, 0x0193, SONY_PN531, "Sony / PN531", 0x84, 0x04, 0x40 },
|
||||
{ 0x1FD3, 0x0608, ASK_LOGO, "ASK / LoGO", 0x84, 0x04, 0x40 },
|
||||
{ 0x054C, 0x02E1, SONY_RCS360, "Sony / FeliCa S360 [PaSoRi]", 0x84, 0x04, 0x40 }
|
||||
};
|
||||
|
||||
// PN533 USB descriptors backup buffers
|
||||
|
||||
const uint8_t btXramUsbDesc_scl3711[] = {
|
||||
0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00,
|
||||
0x00, 0x02, 0xff, 0xff, 0xff, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00,
|
||||
0x04, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x04, 0x1e, 0x03, 0x53, 0x00,
|
||||
0x43, 0x00, 0x4c, 0x00, 0x33, 0x00, 0x37, 0x00, 0x31, 0x00, 0x31, 0x00,
|
||||
0x2d, 0x00, 0x4e, 0x00, 0x46, 0x00, 0x43, 0x00, 0x26, 0x00, 0x52, 0x00,
|
||||
0x57,
|
||||
};
|
||||
const uint8_t btXramUsbDesc_nxppn533[] = {
|
||||
0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00,
|
||||
0x00, 0x02, 0xff, 0xff, 0xff, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00,
|
||||
0x04, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x04, 0x0c, 0x03, 0x50, 0x00,
|
||||
0x4e, 0x00, 0x35, 0x00, 0x33, 0x00, 0x33, 0x00, 0x04, 0x03, 0x09, 0x04,
|
||||
0x08, 0x03, 0x4e, 0x00, 0x58, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00,
|
||||
};
|
||||
const uint8_t btXramUsbDesc_asklogo[] = {
|
||||
0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0x96, 0x09, 0x04, 0x00,
|
||||
0x00, 0x02, 0xff, 0xff, 0xff, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00,
|
||||
0x04, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x04, 0x0a, 0x03, 0x4c, 0x00,
|
||||
0x6f, 0x00, 0x47, 0x00, 0x4f, 0x00, 0x04, 0x03, 0x09, 0x04, 0x08, 0x03,
|
||||
0x41, 0x00, 0x53, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static void pn533_fix_usbdesc(nfc_device *pnd)
|
||||
{
|
||||
// PN533 USB descriptors may have been corrupted by large commands/responses
|
||||
// so they need to be restored before closing usb connection.
|
||||
// cf PN5331B3HNC270 Release Note
|
||||
uint32_t szXramUsbDesc = 0;
|
||||
uint8_t *btXramUsbDesc = NULL;
|
||||
if (DRIVER_DATA(pnd)->model == NXP_PN533) {
|
||||
btXramUsbDesc = (uint8_t *)btXramUsbDesc_nxppn533;
|
||||
szXramUsbDesc = sizeof(btXramUsbDesc_nxppn533);
|
||||
} else if (DRIVER_DATA(pnd)->model == SCM_SCL3711) {
|
||||
btXramUsbDesc = (uint8_t *)btXramUsbDesc_scl3711;
|
||||
szXramUsbDesc = sizeof(btXramUsbDesc_scl3711);
|
||||
} else if (DRIVER_DATA(pnd)->model == ASK_LOGO) {
|
||||
btXramUsbDesc = (uint8_t *)btXramUsbDesc_asklogo;
|
||||
szXramUsbDesc = sizeof(btXramUsbDesc_asklogo);
|
||||
}
|
||||
#define MAXSZXRAMUSBDESC 61
|
||||
if ((szXramUsbDesc == 0) || (MAXSZXRAMUSBDESC > 61))
|
||||
return;
|
||||
#if 0
|
||||
// Debug routine to check if corruption occurred:
|
||||
// Don't read more regs at once or it will trigger the bug and corrupt what we're busy reading!
|
||||
uint8_t abtCmdRR[] = { ReadRegister, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t nRRreg = ((sizeof(abtCmdRR) - 1) / 2);
|
||||
uint8_t abtRxRR[1 + nRRreg];
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "%s", "Checking USB descriptors corruption in XRAM");
|
||||
for (uint8_t i = 0x19, j = 0; i < 0x19 + szXramUsbDesc;) {
|
||||
for (uint8_t k = 0; k < nRRreg; k++) {
|
||||
abtCmdRR[(2 * k) + 2] = i++;
|
||||
}
|
||||
if (pn53x_transceive(pnd, abtCmdRR, sizeof(abtCmdRR), abtRxRR, sizeof(abtRxRR), -1) < 0) {
|
||||
return; // void
|
||||
}
|
||||
for (int k = 0; (k < nRRreg) && (j < szXramUsbDesc); k++) {
|
||||
//printf("0x%02x, ", abtRxRR[1 + k]);
|
||||
if (btXramUsbDesc[j] != abtRxRR[1 + k])
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "XRAM corruption @ addr 0x00%02X: got %02x, expected %02x", 0x0019 + (j - 1), abtRxRR[1 + k], btXramUsbDesc[j]);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Abuse the overflow bug to restore USB descriptors in one go
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "%s", "Fixing USB descriptors corruption");
|
||||
uint8_t abtCmdWR[19 + MAXSZXRAMUSBDESC] = { GetFirmwareVersion };
|
||||
for (uint8_t i = 0; i < szXramUsbDesc; i++) {
|
||||
abtCmdWR[i + 19] = btXramUsbDesc[i];
|
||||
}
|
||||
size_t szCmdWR = sizeof(abtCmdWR);
|
||||
uint8_t abtRxWR[4];
|
||||
if (pn53x_transceive(pnd, abtCmdWR, szCmdWR, abtRxWR, sizeof(abtRxWR), -1) < 0) {
|
||||
return; // void
|
||||
}
|
||||
DRIVER_DATA(pnd)->possibly_corrupted_usbdesc = false;
|
||||
}
|
||||
|
||||
static pn53x_usb_model
|
||||
pn53x_usb_get_device_model(uint16_t vendor_id, uint16_t product_id)
|
||||
{
|
||||
@ -144,6 +238,25 @@ pn53x_usb_get_device_model(uint16_t vendor_id, uint16_t product_id)
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
static bool
|
||||
pn53x_usb_get_end_points_default(struct usb_device *dev, struct pn53x_usb_data *data)
|
||||
{
|
||||
for (size_t n = 0; n < sizeof(pn53x_usb_supported_devices) / sizeof(struct pn53x_usb_supported_device); n++) {
|
||||
if ((dev->descriptor.idVendor == pn53x_usb_supported_devices[n].vendor_id) &&
|
||||
(dev->descriptor.idProduct == pn53x_usb_supported_devices[n].product_id)) {
|
||||
if (pn53x_usb_supported_devices[n].uiMaxPacketSize != 0) {
|
||||
data->uiEndPointIn = pn53x_usb_supported_devices[n].uiEndPointIn;
|
||||
data->uiEndPointOut = pn53x_usb_supported_devices[n].uiEndPointOut;
|
||||
data->uiMaxPacketSize = pn53x_usb_supported_devices[n].uiMaxPacketSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int pn53x_usb_ack(nfc_device *pnd);
|
||||
|
||||
// Find transfer endpoints for bulk transfers
|
||||
@ -194,14 +307,20 @@ pn53x_usb_scan(const nfc_context *context, nfc_connstring connstrings[], const s
|
||||
if ((pn53x_usb_supported_devices[n].vendor_id == dev->descriptor.idVendor) &&
|
||||
(pn53x_usb_supported_devices[n].product_id == dev->descriptor.idProduct)) {
|
||||
// Make sure there are 2 endpoints available
|
||||
// with libusb-win32 we got some null pointers so be robust before looking at endpoints:
|
||||
if (dev->config == NULL || dev->config->interface == NULL || dev->config->interface->altsetting == NULL) {
|
||||
// Nope, we maybe want the next one, let's try to find another
|
||||
continue;
|
||||
}
|
||||
if (dev->config->interface->altsetting->bNumEndpoints < 2) {
|
||||
// Nope, we maybe want the next one, let's try to find another
|
||||
continue;
|
||||
// libusb-win32 may return a NULL dev->config,
|
||||
// or the descriptors may be corrupted, hence
|
||||
// let us assume we will use hardcoded defaults
|
||||
// from pn53x_usb_supported_devices if available.
|
||||
// otherwise get data from the descriptors.
|
||||
if (pn53x_usb_supported_devices[n].uiMaxPacketSize == 0) {
|
||||
if (dev->config->interface == NULL || dev->config->interface->altsetting == NULL) {
|
||||
// Nope, we maybe want the next one, let's try to find another
|
||||
continue;
|
||||
}
|
||||
if (dev->config->interface->altsetting->bNumEndpoints < 2) {
|
||||
// Nope, we maybe want the next one, let's try to find another
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
usb_dev_handle *udev = usb_open(dev);
|
||||
@ -220,7 +339,10 @@ pn53x_usb_scan(const nfc_context *context, nfc_connstring connstrings[], const s
|
||||
// pn53x_usb_get_usb_device_name (dev, udev, pnddDevices[device_found].acDevice, sizeof (pnddDevices[device_found].acDevice));
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "device found: Bus %s Device %s", bus->dirname, dev->filename);
|
||||
usb_close(udev);
|
||||
snprintf(connstrings[device_found], sizeof(nfc_connstring), "%s:%s:%s", PN53X_USB_DRIVER_NAME, bus->dirname, dev->filename);
|
||||
if (snprintf(connstrings[device_found], sizeof(nfc_connstring), "%s:%s:%s", PN53X_USB_DRIVER_NAME, bus->dirname, dev->filename) >= (int)sizeof(nfc_connstring)) {
|
||||
// truncation occurred, skipping that one
|
||||
continue;
|
||||
}
|
||||
device_found++;
|
||||
// Test if we reach the maximum "wanted" devices
|
||||
if (device_found == connstrings_len) {
|
||||
@ -282,6 +404,7 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring)
|
||||
.pudh = NULL,
|
||||
.uiEndPointIn = 0,
|
||||
.uiEndPointOut = 0,
|
||||
.possibly_corrupted_usbdesc = false,
|
||||
};
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
@ -303,8 +426,16 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring)
|
||||
// Open the USB device
|
||||
if ((data.pudh = usb_open(dev)) == NULL)
|
||||
continue;
|
||||
// Retrieve end points
|
||||
pn53x_usb_get_end_points(dev, &data);
|
||||
|
||||
//To retrieve real USB endpoints configuration:
|
||||
//pn53x_usb_get_end_points(dev, &data);
|
||||
//printf("DEBUG ENDPOINTS In:0x%x Out:0x%x Size:0x%x\n", data.uiEndPointIn, data.uiEndPointOut, data.uiMaxPacketSize);
|
||||
|
||||
// Retrieve end points, using hardcoded defaults if available
|
||||
// or using the descriptors otherwise.
|
||||
if (pn53x_usb_get_end_points_default(dev, &data) == false) {
|
||||
pn53x_usb_get_end_points(dev, &data);
|
||||
}
|
||||
// Set configuration
|
||||
int res = usb_set_configuration(data.pudh, 1);
|
||||
if (res < 0) {
|
||||
@ -347,11 +478,13 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring)
|
||||
}
|
||||
|
||||
switch (DRIVER_DATA(pnd)->model) {
|
||||
// empirical tuning
|
||||
// empirical tuning
|
||||
case ASK_LOGO:
|
||||
CHIP_DATA(pnd)->timer_correction = 50;
|
||||
CHIP_DATA(pnd)->progressive_field = true;
|
||||
break;
|
||||
case SCM_SCL3711:
|
||||
case SCM_SCL3712:
|
||||
case NXP_PN533:
|
||||
CHIP_DATA(pnd)->timer_correction = 46;
|
||||
break;
|
||||
@ -405,6 +538,9 @@ pn53x_usb_close(nfc_device *pnd)
|
||||
pn53x_write_register(pnd, PN53X_SFR_P3, 0xFF, _BV(P30) | _BV(P31) | _BV(P32) | _BV(P33) | _BV(P35));
|
||||
}
|
||||
|
||||
if (DRIVER_DATA(pnd)->possibly_corrupted_usbdesc)
|
||||
pn533_fix_usbdesc(pnd);
|
||||
|
||||
pn53x_idle(pnd);
|
||||
|
||||
int res;
|
||||
@ -433,6 +569,7 @@ pn53x_usb_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, con
|
||||
return pnd->last_error;
|
||||
}
|
||||
|
||||
DRIVER_DATA(pnd)->possibly_corrupted_usbdesc |= szData > 17;
|
||||
if ((res = pn53x_usb_bulk_write(DRIVER_DATA(pnd), abtFrame, szFrame, timeout)) < 0) {
|
||||
pnd->last_error = res;
|
||||
return pnd->last_error;
|
||||
@ -452,8 +589,8 @@ pn53x_usb_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, con
|
||||
// For some reasons (eg. send another command while a previous one is
|
||||
// running), the PN533 sometimes directly replies the response packet
|
||||
// instead of ACK frame, so we send a NACK frame to force PN533 to resend
|
||||
// response packet. With this hack, the nextly executed function (ie.
|
||||
// pn53x_usb_receive()) will be able to retreive the correct response
|
||||
// response packet. With this hack, the next executed function (ie.
|
||||
// pn53x_usb_receive()) will be able to retrieve the correct response
|
||||
// packet.
|
||||
// FIXME Sony reader is also affected by this bug but NACK is not supported
|
||||
if ((res = pn53x_usb_bulk_write(DRIVER_DATA(pnd), (uint8_t *)pn53x_nack_frame, sizeof(pn53x_nack_frame), timeout)) < 0) {
|
||||
@ -463,7 +600,6 @@ pn53x_usb_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, con
|
||||
return pnd->last_error;
|
||||
}
|
||||
}
|
||||
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
@ -487,7 +623,7 @@ read:
|
||||
if (timeout == USB_INFINITE_TIMEOUT) {
|
||||
usb_timeout = USB_TIMEOUT_PER_PASS;
|
||||
} else {
|
||||
// A user-provided timeout is set, we have to cut it in multiple chunk to be able to keep an nfc_abort_command() mecanism
|
||||
// A user-provided timeout is set, we have to cut it in multiple chunk to be able to keep an nfc_abort_command() mechanism
|
||||
remaining_time -= USB_TIMEOUT_PER_PASS;
|
||||
if (remaining_time <= 0) {
|
||||
pnd->last_error = NFC_ETIMEOUT;
|
||||
@ -601,6 +737,7 @@ read:
|
||||
}
|
||||
// The PN53x command is done and we successfully received the reply
|
||||
pnd->last_error = 0;
|
||||
DRIVER_DATA(pnd)->possibly_corrupted_usbdesc |= len > 16;
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -664,6 +801,8 @@ pn53x_usb_init(nfc_device *pnd)
|
||||
/* ie. Switch LED1 on and turn off progressive field */
|
||||
pn53x_write_register(pnd, PN53X_SFR_P3, 0xFF, _BV(P30) | _BV(P31) | _BV(P33) | _BV(P35));
|
||||
}
|
||||
if (DRIVER_DATA(pnd)->possibly_corrupted_usbdesc)
|
||||
pn533_fix_usbdesc(pnd);
|
||||
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
@ -680,7 +819,7 @@ pn53x_usb_set_property_bool(nfc_device *pnd, const nfc_property property, const
|
||||
if (NP_ACTIVATE_FIELD == property) {
|
||||
/* Switch on/off LED2 and Progressive Field GPIO according to ACTIVATE_FIELD option */
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Switch progressive field %s", bEnable ? "On" : "Off");
|
||||
if ((res = pn53x_write_register(pnd, PN53X_SFR_P3, _BV(P31) | _BV(P34), bEnable ? _BV(P34) : _BV(P31))) < 0)
|
||||
if (pn53x_write_register(pnd, PN53X_SFR_P3, _BV(P31) | _BV(P34), bEnable ? _BV(P34) : _BV(P31)) < 0)
|
||||
return NFC_ECHIP;
|
||||
}
|
||||
break;
|
||||
@ -691,6 +830,13 @@ pn53x_usb_set_property_bool(nfc_device *pnd, const nfc_property property, const
|
||||
return res;
|
||||
}
|
||||
break;
|
||||
case SCM_SCL3712:
|
||||
if (NP_ACTIVATE_FIELD == property) {
|
||||
// Switch on/off LED according to ACTIVATE_FIELD option
|
||||
if ((res = pn53x_write_register(pnd, PN53X_SFR_P3, _BV(P32), bEnable ? 0 : _BV(P32))) < 0)
|
||||
return res;
|
||||
}
|
||||
break;
|
||||
case NXP_PN531:
|
||||
case NXP_PN533:
|
||||
case SONY_PN531:
|
||||
@ -709,6 +855,16 @@ pn53x_usb_abort_command(nfc_device *pnd)
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
pn53x_usb_get_supported_modulation(nfc_device *pnd, const nfc_mode mode, const nfc_modulation_type **const supported_mt)
|
||||
{
|
||||
if ((DRIVER_DATA(pnd)->model != ASK_LOGO) || (mode != N_TARGET))
|
||||
return pn53x_get_supported_modulation(pnd, mode, supported_mt);
|
||||
else // ASK_LOGO has no N_TARGET support
|
||||
*supported_mt = no_target_support;
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
const struct pn53x_io pn53x_usb_io = {
|
||||
.send = pn53x_usb_send,
|
||||
.receive = pn53x_usb_receive,
|
||||
@ -742,7 +898,7 @@ const struct nfc_driver pn53x_usb_driver = {
|
||||
|
||||
.device_set_property_bool = pn53x_usb_set_property_bool,
|
||||
.device_set_property_int = pn53x_set_property_int,
|
||||
.get_supported_modulation = pn53x_get_supported_modulation,
|
||||
.get_supported_modulation = pn53x_usb_get_supported_modulation,
|
||||
.get_supported_baud_rate = pn53x_get_supported_baud_rate,
|
||||
.device_get_information_about = pn53x_get_information_about,
|
||||
|
||||
|
||||
589
libnfc/drivers/pn71xx.c
Normal file
589
libnfc/drivers/pn71xx.c
Normal file
@ -0,0 +1,589 @@
|
||||
|
||||
/**
|
||||
* @file pn71xx.h
|
||||
* @brief Driver for PN71XX using libnfc-nci library
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include "pn71xx.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
|
||||
#include "drivers.h"
|
||||
#include "nfc-internal.h"
|
||||
|
||||
#include "linux_nfc_api.h"
|
||||
|
||||
#define PN71XX_DRIVER_NAME "pn71xx"
|
||||
|
||||
#define LOG_CATEGORY "libnfc.driver.pn71xx"
|
||||
#define LOG_GROUP NFC_LOG_GROUP_DRIVER
|
||||
|
||||
const nfc_modulation_type pn71xx_supported_modulation_as_target[] = {NMT_ISO14443A, NMT_FELICA, NMT_ISO14443B, NMT_ISO14443BI, NMT_ISO14443B2SR, NMT_ISO14443B2CT, NMT_JEWEL, NMT_DEP, 0};
|
||||
const nfc_modulation_type pn71xx_supported_modulation_as_initiator[] = {NMT_ISO14443A, NMT_FELICA, NMT_ISO14443B, NMT_ISO14443BI, NMT_ISO14443B2SR, NMT_ISO14443B2CT, NMT_JEWEL, NMT_DEP, 0};
|
||||
|
||||
const nfc_baud_rate pn71xx_iso14443a_supported_baud_rates[] = { NBR_847, NBR_424, NBR_212, NBR_106, 0 };
|
||||
const nfc_baud_rate pn71xx_felica_supported_baud_rates[] = { NBR_424, NBR_212, 0 };
|
||||
const nfc_baud_rate pn71xx_dep_supported_baud_rates[] = { NBR_424, NBR_212, NBR_106, 0 };
|
||||
const nfc_baud_rate pn71xx_jewel_supported_baud_rates[] = { NBR_847, NBR_424, NBR_212, NBR_106, 0 };
|
||||
const nfc_baud_rate pn71xx_iso14443b_supported_baud_rates[] = { NBR_847, NBR_424, NBR_212, NBR_106, 0 };
|
||||
|
||||
static nfcTagCallback_t TagCB;
|
||||
static nfc_tag_info_t *TagInfo = NULL;
|
||||
|
||||
static void onTagArrival(nfc_tag_info_t *pTagInfo);
|
||||
static void onTagDeparture(void);
|
||||
|
||||
/** ------------------------------------------------------------------------ */
|
||||
/** ------------------------------------------------------------------------ */
|
||||
/**
|
||||
* @brief Initialize libnfc_nci library to verify presence of PN71xx device.
|
||||
*
|
||||
* @param context NFC context.
|
||||
* @param connstrings array of 'nfc_connstring' buffer (allocated by caller). It is used to store the
|
||||
* connection info strings of devices found.
|
||||
* @param connstrings_len length of the connstrings array.
|
||||
* @return number of devices found.
|
||||
*/
|
||||
static size_t
|
||||
pn71xx_scan(const nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
|
||||
{
|
||||
size_t device_found = 0;
|
||||
|
||||
if ((context == NULL) || (connstrings_len == 0)) return 0;
|
||||
|
||||
if (nfcManager_doInitialize() == 0) {
|
||||
nfc_connstring connstring = "pn71xx";
|
||||
memcpy(connstrings[device_found++], connstring, sizeof(nfc_connstring));
|
||||
}
|
||||
|
||||
return device_found;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Close connection to PN71xx by stopping the discovery loop and deinitializing the libnfc_nci library.
|
||||
*
|
||||
* @param pnd pointer on the device to close.
|
||||
*/
|
||||
static void
|
||||
pn71xx_close(nfc_device *pnd)
|
||||
{
|
||||
nfcManager_disableDiscovery();
|
||||
nfcManager_deregisterTagCallback();
|
||||
nfcManager_doDeinitialize();
|
||||
nfc_device_free(pnd);
|
||||
pnd = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open a connection to PN71xx, starting the discovery loop for tag detection.
|
||||
*
|
||||
* @param context NFC context.
|
||||
* @param connstring connection info to the device
|
||||
* @return pointer to the device, or NULL in case of error.
|
||||
*/
|
||||
static nfc_device *
|
||||
pn71xx_open(const nfc_context *context, const nfc_connstring connstring)
|
||||
{
|
||||
nfc_device *pnd;
|
||||
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "open: %s", connstring);
|
||||
|
||||
pnd = nfc_device_new(context, connstring);
|
||||
if (!pnd) {
|
||||
perror("malloc");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pnd->driver = &pn71xx_driver;
|
||||
strcpy(pnd->name, "pn71xx-device");
|
||||
strcpy(pnd->connstring, connstring);
|
||||
|
||||
TagCB.onTagArrival = onTagArrival;
|
||||
TagCB.onTagDeparture = onTagDeparture;
|
||||
nfcManager_registerTagCallback(&TagCB);
|
||||
|
||||
nfcManager_enableDiscovery(DEFAULT_NFA_TECH_MASK, 1, 0, 0);
|
||||
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "wait 1 seconds for polling");
|
||||
sleep(1);
|
||||
|
||||
return pnd;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------------------------------ */
|
||||
/** ------------------------------------------------------------------------ */
|
||||
static bool IsTechnology(nfc_tag_info_t *TagInfo, nfc_modulation_type nmt)
|
||||
{
|
||||
switch (nmt) {
|
||||
case NMT_ISO14443A:
|
||||
if (TagInfo->technology == TARGET_TYPE_ISO14443_4
|
||||
|| TagInfo->technology == TARGET_TYPE_ISO14443_3A
|
||||
|| TagInfo->technology == TARGET_TYPE_MIFARE_CLASSIC
|
||||
|| TagInfo->technology == TARGET_TYPE_MIFARE_UL)
|
||||
return true;
|
||||
break;
|
||||
|
||||
case NMT_ISO14443B:
|
||||
case NMT_ISO14443BI:
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT:
|
||||
if (TagInfo->technology == TARGET_TYPE_ISO14443_3B)
|
||||
return true;
|
||||
break;
|
||||
|
||||
case NMT_FELICA:
|
||||
if (TagInfo->technology == TARGET_TYPE_FELICA)
|
||||
return true;
|
||||
break;
|
||||
|
||||
case NMT_JEWEL:
|
||||
if (TagInfo->technology == TARGET_TYPE_ISO14443_3A
|
||||
&& TagInfo->protocol == NFA_PROTOCOL_T1T)
|
||||
return true;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void BufferPrintBytes(char *buffer, unsigned int buflen, const uint8_t *data, unsigned int datalen)
|
||||
{
|
||||
int cx = 0;
|
||||
for (unsigned int i = 0x00; i < datalen; i++) {
|
||||
cx += snprintf(buffer + cx, buflen - cx, "%02X ", data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintTagInfo(nfc_tag_info_t *TagInfo)
|
||||
{
|
||||
switch (TagInfo->technology) {
|
||||
case TARGET_TYPE_UNKNOWN: {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "'Type Unknown'");
|
||||
}
|
||||
break;
|
||||
case TARGET_TYPE_ISO14443_3A: {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "'Type 3A'");
|
||||
}
|
||||
break;
|
||||
case TARGET_TYPE_ISO14443_3B: {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "'Type 3B'");
|
||||
}
|
||||
break;
|
||||
case TARGET_TYPE_ISO14443_4: {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "'Type 4A'");
|
||||
}
|
||||
break;
|
||||
case TARGET_TYPE_FELICA: {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "'Type F'");
|
||||
}
|
||||
break;
|
||||
case TARGET_TYPE_ISO15693: {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "'Type V'");
|
||||
}
|
||||
break;
|
||||
case TARGET_TYPE_NDEF: {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "'Type NDEF'");
|
||||
}
|
||||
break;
|
||||
case TARGET_TYPE_NDEF_FORMATABLE: {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "'Type Formatable'");
|
||||
}
|
||||
break;
|
||||
case TARGET_TYPE_MIFARE_CLASSIC: {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "'Type A - Mifare Classic'");
|
||||
}
|
||||
break;
|
||||
case TARGET_TYPE_MIFARE_UL: {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "'Type A - Mifare Ul'");
|
||||
}
|
||||
break;
|
||||
case TARGET_TYPE_KOVIO_BARCODE: {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "'Type A - Kovio Barcode'");
|
||||
}
|
||||
break;
|
||||
case TARGET_TYPE_ISO14443_3A_3B: {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "'Type A/B'");
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "'Type %d (Unknown or not supported)'\n", TagInfo->technology);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*32 is max UID len (Kovio tags)*/
|
||||
if ((0x00 != TagInfo->uid_length) && (32 >= TagInfo->uid_length)) {
|
||||
char buffer [100];
|
||||
int cx = 0;
|
||||
|
||||
if (4 == TagInfo->uid_length || 7 == TagInfo->uid_length || 10 == TagInfo->uid_length) {
|
||||
cx += snprintf(buffer + cx, sizeof(buffer) - cx, "NFCID1 : \t'");
|
||||
} else if (8 == TagInfo->uid_length) {
|
||||
cx += snprintf(buffer + cx, sizeof(buffer) - cx, "NFCID2 : \t'");
|
||||
} else {
|
||||
cx += snprintf(buffer + cx, sizeof(buffer) - cx, "UID : \t'");
|
||||
}
|
||||
|
||||
BufferPrintBytes(buffer + cx, sizeof(buffer) - cx, (unsigned char *) TagInfo->uid, TagInfo->uid_length);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s'", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/** ------------------------------------------------------------------------ */
|
||||
/** ------------------------------------------------------------------------ */
|
||||
|
||||
static void onTagArrival(nfc_tag_info_t *pTagInfo)
|
||||
{
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "tag found");
|
||||
|
||||
TagInfo = malloc(sizeof(nfc_tag_info_t));
|
||||
memcpy(TagInfo, pTagInfo, sizeof(nfc_tag_info_t));
|
||||
|
||||
PrintTagInfo(TagInfo);
|
||||
}
|
||||
|
||||
static void onTagDeparture(void)
|
||||
{
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "tag lost");
|
||||
|
||||
free(TagInfo);
|
||||
TagInfo = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
pn71xx_initiator_init(struct nfc_device *pnd)
|
||||
{
|
||||
if (pnd == NULL) return NFC_EIO;
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
pn71xx_initiator_select_passive_target(struct nfc_device *pnd,
|
||||
const nfc_modulation nm,
|
||||
const uint8_t *pbtInitData, const size_t szInitData,
|
||||
nfc_target *pnt)
|
||||
{
|
||||
if (pnd == NULL) return NFC_EIO;
|
||||
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "select_passive_target");
|
||||
|
||||
if (TagInfo) {
|
||||
|
||||
nfc_target nttmp;
|
||||
memset(&nttmp, 0x00, sizeof(nfc_target));
|
||||
nttmp.nm = nm;
|
||||
|
||||
void *uidPtr = NULL;
|
||||
unsigned int maxLen = 0;
|
||||
|
||||
switch (nm.nmt) {
|
||||
case NMT_ISO14443A:
|
||||
if (IsTechnology(TagInfo, nm.nmt)) {
|
||||
maxLen = 10;
|
||||
uidPtr = nttmp.nti.nai.abtUid;
|
||||
|
||||
if (TagInfo->technology == TARGET_TYPE_MIFARE_CLASSIC) {
|
||||
nttmp.nti.nai.btSak = 0x08;
|
||||
} else {
|
||||
// make hardcoded desfire for freefare lib check
|
||||
nttmp.nti.nai.btSak = 0x20;
|
||||
nttmp.nti.nai.szAtsLen = 5;
|
||||
memcpy(nttmp.nti.nai.abtAts, "\x75\x77\x81\x02", 4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NMT_ISO14443B:
|
||||
if (IsTechnology(TagInfo, nm.nmt)) {
|
||||
maxLen = 4;
|
||||
uidPtr = nttmp.nti.nbi.abtPupi;
|
||||
}
|
||||
break;
|
||||
|
||||
case NMT_ISO14443BI:
|
||||
if (IsTechnology(TagInfo, nm.nmt)) {
|
||||
maxLen = 4;
|
||||
uidPtr = nttmp.nti.nii.abtDIV;
|
||||
}
|
||||
break;
|
||||
|
||||
case NMT_ISO14443B2SR:
|
||||
if (IsTechnology(TagInfo, nm.nmt)) {
|
||||
maxLen = 8;
|
||||
uidPtr = nttmp.nti.nsi.abtUID;
|
||||
}
|
||||
break;
|
||||
|
||||
case NMT_ISO14443B2CT:
|
||||
if (IsTechnology(TagInfo, nm.nmt)) {
|
||||
maxLen = 4;
|
||||
uidPtr = nttmp.nti.nci.abtUID;
|
||||
}
|
||||
break;
|
||||
|
||||
case NMT_FELICA:
|
||||
if (IsTechnology(TagInfo, nm.nmt)) {
|
||||
maxLen = 8;
|
||||
uidPtr = nttmp.nti.nfi.abtId;
|
||||
}
|
||||
break;
|
||||
|
||||
case NMT_JEWEL:
|
||||
if (IsTechnology(TagInfo, nm.nmt)) {
|
||||
maxLen = 4;
|
||||
uidPtr = nttmp.nti.nji.btId;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (uidPtr && TagInfo->uid_length) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "target found");
|
||||
int len = TagInfo->uid_length > maxLen ? maxLen : TagInfo->uid_length;
|
||||
memcpy(uidPtr, TagInfo->uid, len);
|
||||
if (nm.nmt == NMT_ISO14443A)
|
||||
nttmp.nti.nai.szUidLen = len;
|
||||
|
||||
// Is a tag info struct available
|
||||
if (pnt) {
|
||||
memcpy(pnt, &nttmp, sizeof(nfc_target));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pn71xx_initiator_deselect_target(struct nfc_device *pnd)
|
||||
{
|
||||
if (pnd == NULL) return NFC_EIO;
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "deselect_passive_target");
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pn71xx_initiator_transceive_bytes(struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx,
|
||||
const size_t szRx, int timeout)
|
||||
{
|
||||
if (pnd == NULL) return NFC_EIO;
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "transceive_bytes timeout=%d", timeout);
|
||||
|
||||
if (!TagInfo) return NFC_EINVARG;
|
||||
|
||||
char buffer[500];
|
||||
BufferPrintBytes(buffer, sizeof(buffer), pbtTx, szTx);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "===> %s", buffer);
|
||||
|
||||
int received = nfcTag_transceive(TagInfo->handle, (uint8_t *) pbtTx, szTx, pbtRx, szRx, 500);
|
||||
if (received <= 0)
|
||||
return NFC_EIO;
|
||||
|
||||
BufferPrintBytes(buffer, sizeof(buffer), pbtRx, received);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "<=== %s", buffer);
|
||||
|
||||
return received;
|
||||
}
|
||||
|
||||
static int
|
||||
pn71xx_initiator_poll_target(struct nfc_device *pnd,
|
||||
const nfc_modulation *pnmModulations, const size_t szModulations,
|
||||
const uint8_t uiPollNr, const uint8_t uiPeriod,
|
||||
nfc_target *pnt)
|
||||
{
|
||||
static int periodFactor = 150000;
|
||||
int period = uiPeriod * periodFactor;
|
||||
|
||||
if (pnd == NULL) return 0;
|
||||
|
||||
for (int j = 0; j < uiPollNr; j++) {
|
||||
for (unsigned int i = 0; i < szModulations; i++) {
|
||||
const nfc_modulation nm = pnmModulations[i];
|
||||
|
||||
nfc_target nt;
|
||||
int res = pn71xx_initiator_select_passive_target(pnd, nm, 0, 0, &nt);
|
||||
if (res > 0 && pnt) {
|
||||
memcpy(pnt, &nt, sizeof(nfc_target));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
usleep(period);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pn71xx_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt)
|
||||
{
|
||||
if ((pnd == NULL) || (pnt == NULL)) return 1;
|
||||
return !TagInfo;
|
||||
}
|
||||
|
||||
|
||||
/** ------------------------------------------------------------------------ */
|
||||
/** ------------------------------------------------------------------------ */
|
||||
static int
|
||||
pn71xx_get_supported_modulation(nfc_device *pnd, const nfc_mode mode, const nfc_modulation_type **const supported_mt)
|
||||
{
|
||||
if (pnd == NULL) return NFC_EIO;
|
||||
|
||||
switch (mode) {
|
||||
case N_TARGET:
|
||||
*supported_mt = (nfc_modulation_type *)pn71xx_supported_modulation_as_target;
|
||||
break;
|
||||
case N_INITIATOR:
|
||||
*supported_mt = (nfc_modulation_type *)pn71xx_supported_modulation_as_initiator;
|
||||
break;
|
||||
default:
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
pn71xx_get_supported_baud_rate(nfc_device *pnd, const nfc_mode mode, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br)
|
||||
{
|
||||
if (pnd == NULL) return NFC_EIO;
|
||||
if (mode) {}
|
||||
|
||||
switch (nmt) {
|
||||
case NMT_FELICA:
|
||||
*supported_br = (nfc_baud_rate *)pn71xx_felica_supported_baud_rates;
|
||||
break;
|
||||
case NMT_ISO14443A:
|
||||
*supported_br = (nfc_baud_rate *)pn71xx_iso14443a_supported_baud_rates;
|
||||
break;
|
||||
case NMT_ISO14443B:
|
||||
case NMT_ISO14443BI:
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT:
|
||||
*supported_br = (nfc_baud_rate *)pn71xx_iso14443b_supported_baud_rates;
|
||||
break;
|
||||
case NMT_JEWEL:
|
||||
*supported_br = (nfc_baud_rate *)pn71xx_jewel_supported_baud_rates;
|
||||
break;
|
||||
case NMT_DEP:
|
||||
*supported_br = (nfc_baud_rate *)pn71xx_dep_supported_baud_rates;
|
||||
break;
|
||||
default:
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------------------------------ */
|
||||
/** ------------------------------------------------------------------------ */
|
||||
|
||||
static int
|
||||
pn71xx_set_property_bool(struct nfc_device *pnd, const nfc_property property, const bool bEnable)
|
||||
{
|
||||
if (pnd == NULL) return NFC_EIO;
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
pn71xx_set_property_int(struct nfc_device *pnd, const nfc_property property, const int value)
|
||||
{
|
||||
if (pnd == NULL) return NFC_EIO;
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
pn71xx_get_information_about(nfc_device *pnd, char **pbuf)
|
||||
{
|
||||
static const char *info = "PN71XX nfc driver using libnfc-nci userspace library";
|
||||
size_t buflen = strlen(info) + 1;
|
||||
|
||||
if (pnd == NULL) return NFC_EIO;
|
||||
|
||||
*pbuf = malloc(buflen);
|
||||
memcpy(*pbuf, info, buflen);
|
||||
|
||||
return buflen;
|
||||
}
|
||||
/**
|
||||
* @brief Abort any pending operation
|
||||
*
|
||||
* @param pnd pointer on the NFC device.
|
||||
* @return NFC_SUCCESS
|
||||
*/
|
||||
static int
|
||||
pn71xx_abort_command(nfc_device *pnd)
|
||||
{
|
||||
if (pnd == NULL) return NFC_EIO;
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "abort_command");
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
pn71xx_idle(struct nfc_device *pnd)
|
||||
{
|
||||
if (pnd == NULL) return NFC_EIO;
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "idle");
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
pn71xx_PowerDown(struct nfc_device *pnd)
|
||||
{
|
||||
if (pnd == NULL) return NFC_EIO;
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "PowerDown");
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------------------------------ */
|
||||
/** ------------------------------------------------------------------------ */
|
||||
const struct nfc_driver pn71xx_driver = {
|
||||
.name = PN71XX_DRIVER_NAME,
|
||||
.scan_type = NOT_INTRUSIVE,
|
||||
.scan = pn71xx_scan,
|
||||
.open = pn71xx_open,
|
||||
.close = pn71xx_close,
|
||||
.strerror = NULL,
|
||||
|
||||
.initiator_init = pn71xx_initiator_init,
|
||||
.initiator_init_secure_element = NULL,
|
||||
.initiator_select_passive_target = pn71xx_initiator_select_passive_target,
|
||||
.initiator_poll_target = pn71xx_initiator_poll_target,
|
||||
.initiator_select_dep_target = NULL,
|
||||
.initiator_deselect_target = pn71xx_initiator_deselect_target,
|
||||
.initiator_transceive_bytes = pn71xx_initiator_transceive_bytes,
|
||||
.initiator_transceive_bits = NULL,
|
||||
.initiator_transceive_bytes_timed = NULL,
|
||||
.initiator_transceive_bits_timed = NULL,
|
||||
.initiator_target_is_present = pn71xx_initiator_target_is_present,
|
||||
|
||||
.target_init = NULL,
|
||||
.target_send_bytes = NULL,
|
||||
.target_receive_bytes = NULL,
|
||||
.target_send_bits = NULL,
|
||||
.target_receive_bits = NULL,
|
||||
|
||||
.device_set_property_bool = pn71xx_set_property_bool,
|
||||
.device_set_property_int = pn71xx_set_property_int,
|
||||
.get_supported_modulation = pn71xx_get_supported_modulation,
|
||||
.get_supported_baud_rate = pn71xx_get_supported_baud_rate,
|
||||
.device_get_information_about = pn71xx_get_information_about,
|
||||
|
||||
.abort_command = pn71xx_abort_command,
|
||||
.idle = pn71xx_idle,
|
||||
.powerdown = pn71xx_PowerDown,
|
||||
};
|
||||
|
||||
14
libnfc/drivers/pn71xx.h
Normal file
14
libnfc/drivers/pn71xx.h
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @file pn71xx.h
|
||||
* @brief Driver for PN71XX using libnfc-nci library
|
||||
*/
|
||||
|
||||
#ifndef __NFC_DRIVER_PN71XX_H__
|
||||
#define __NFC_DRIVER_PN71XX_H__
|
||||
|
||||
#include <nfc/nfc-types.h>
|
||||
|
||||
/* Reference to the driver structure */
|
||||
extern const struct nfc_driver pn71xx_driver;
|
||||
|
||||
#endif // ! __NFC_DRIVER_7120_H__
|
||||
@ -47,10 +47,10 @@
|
||||
void
|
||||
iso14443a_crc(uint8_t *pbtData, size_t szLen, uint8_t *pbtCrc)
|
||||
{
|
||||
uint8_t bt;
|
||||
uint32_t wCrc = 0x6363;
|
||||
|
||||
do {
|
||||
uint8_t bt;
|
||||
bt = *pbtData++;
|
||||
bt = (bt ^ (uint8_t)(wCrc & 0x00FF));
|
||||
bt = (bt ^ (bt << 4));
|
||||
@ -78,10 +78,10 @@ iso14443a_crc_append(uint8_t *pbtData, size_t szLen)
|
||||
void
|
||||
iso14443b_crc(uint8_t *pbtData, size_t szLen, uint8_t *pbtCrc)
|
||||
{
|
||||
uint8_t bt;
|
||||
uint32_t wCrc = 0xFFFF;
|
||||
|
||||
do {
|
||||
uint8_t bt;
|
||||
bt = *pbtData++;
|
||||
bt = (bt ^ (uint8_t)(wCrc & 0x00FF));
|
||||
bt = (bt ^ (bt << 4));
|
||||
|
||||
@ -39,6 +39,5 @@
|
||||
uint8_t mirror(uint8_t bt);
|
||||
uint32_t mirror32(uint32_t ui32Bits);
|
||||
uint64_t mirror64(uint64_t ui64Bits);
|
||||
void mirror_uint8_ts(uint8_t *pbts, size_t szLen);
|
||||
|
||||
#endif // _LIBNFC_MIRROR_SUBR_H_
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||
* See AUTHORS file for a more comprehensive list of contributors.
|
||||
* Additional contributors of this file:
|
||||
* Copyright (C) 2020 Adam Laurie
|
||||
*
|
||||
* 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
|
||||
@ -169,38 +170,27 @@ void
|
||||
prepare_initiator_data(const nfc_modulation nm, uint8_t **ppbtInitiatorData, size_t *pszInitiatorData)
|
||||
{
|
||||
switch (nm.nmt) {
|
||||
case NMT_ISO14443B: {
|
||||
case NMT_ISO14443B:
|
||||
// Application Family Identifier (AFI) must equals 0x00 in order to wakeup all ISO14443-B PICCs (see ISO/IEC 14443-3)
|
||||
*ppbtInitiatorData = (uint8_t *) "\x00";
|
||||
*pszInitiatorData = 1;
|
||||
}
|
||||
break;
|
||||
case NMT_ISO14443BI: {
|
||||
break;
|
||||
case NMT_ISO14443BI:
|
||||
// APGEN
|
||||
*ppbtInitiatorData = (uint8_t *) "\x01\x0b\x3f\x80";
|
||||
*pszInitiatorData = 4;
|
||||
}
|
||||
break;
|
||||
case NMT_ISO14443B2SR: {
|
||||
// Get_UID
|
||||
*ppbtInitiatorData = (uint8_t *) "\x0b";
|
||||
*pszInitiatorData = 1;
|
||||
}
|
||||
break;
|
||||
case NMT_ISO14443B2CT: {
|
||||
// SELECT-ALL
|
||||
*ppbtInitiatorData = (uint8_t *) "\x9F\xFF\xFF";
|
||||
*pszInitiatorData = 3;
|
||||
}
|
||||
break;
|
||||
case NMT_FELICA: {
|
||||
break;
|
||||
case NMT_FELICA:
|
||||
// polling payload must be present (see ISO/IEC 18092 11.2.2.5)
|
||||
*ppbtInitiatorData = (uint8_t *) "\x00\xff\xff\x01\x00";
|
||||
*pszInitiatorData = 5;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case NMT_ISO14443A:
|
||||
case NMT_ISO14443B2CT:
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443BICLASS:
|
||||
case NMT_JEWEL:
|
||||
case NMT_BARCODE:
|
||||
case NMT_DEP:
|
||||
*ppbtInitiatorData = NULL;
|
||||
*pszInitiatorData = 0;
|
||||
@ -242,7 +232,6 @@ connstring_decode(const nfc_connstring connstring, const char *driver_name, cons
|
||||
int res = sscanf(connstring, format, param0, param1, param2);
|
||||
|
||||
if (res < 1 || ((0 != strcmp(param0, driver_name)) &&
|
||||
(bus_name != NULL) &&
|
||||
(0 != strcmp(param0, bus_name)))) {
|
||||
// Driver name does not match.
|
||||
res = 0;
|
||||
|
||||
@ -34,7 +34,9 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <err.h>
|
||||
#if !defined(_MSC_VER)
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "nfc/nfc.h"
|
||||
|
||||
@ -148,7 +150,7 @@ struct nfc_driver {
|
||||
int (*device_set_property_bool)(struct nfc_device *pnd, const nfc_property property, const bool bEnable);
|
||||
int (*device_set_property_int)(struct nfc_device *pnd, const nfc_property property, const int value);
|
||||
int (*get_supported_modulation)(struct nfc_device *pnd, const nfc_mode mode, const nfc_modulation_type **const supported_mt);
|
||||
int (*get_supported_baud_rate)(struct nfc_device *pnd, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br);
|
||||
int (*get_supported_baud_rate)(struct nfc_device *pnd, const nfc_mode mode, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br);
|
||||
int (*device_get_information_about)(struct nfc_device *pnd, char **buf);
|
||||
|
||||
int (*abort_command)(struct nfc_device *pnd);
|
||||
|
||||
169
libnfc/nfc.c
169
libnfc/nfc.c
@ -9,6 +9,7 @@
|
||||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||
* See AUTHORS file for a more comprehensive list of contributors.
|
||||
* Additional contributors of this file:
|
||||
* Copyright (C) 2020 Adam Laurie
|
||||
*
|
||||
* 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
|
||||
@ -79,6 +80,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
|
||||
@ -86,6 +88,10 @@
|
||||
#include "target-subr.h"
|
||||
#include "drivers.h"
|
||||
|
||||
#if defined (DRIVER_PCSC_ENABLED)
|
||||
# include "drivers/pcsc.h"
|
||||
#endif /* DRIVER_PCSC_ENABLED */
|
||||
|
||||
#if defined (DRIVER_ACR122_PCSC_ENABLED)
|
||||
# include "drivers/acr122_pcsc.h"
|
||||
#endif /* DRIVER_ACR122_PCSC_ENABLED */
|
||||
@ -118,6 +124,10 @@
|
||||
# include "drivers/pn532_i2c.h"
|
||||
#endif /* DRIVER_PN532_I2C_ENABLED */
|
||||
|
||||
#if defined (DRIVER_PN71XX_ENABLED)
|
||||
# include "drivers/pn71xx.h"
|
||||
#endif /* DRIVER_PN71XX_ENABLED */
|
||||
|
||||
|
||||
#define LOG_CATEGORY "libnfc.general"
|
||||
#define LOG_GROUP NFC_LOG_GROUP_GENERAL
|
||||
@ -129,12 +139,34 @@ struct nfc_driver_list {
|
||||
|
||||
const struct nfc_driver_list *nfc_drivers = NULL;
|
||||
|
||||
// descritions for debugging
|
||||
const char *nfc_property_name[] = {
|
||||
"NP_TIMEOUT_COMMAND",
|
||||
"NP_TIMEOUT_ATR",
|
||||
"NP_TIMEOUT_COM",
|
||||
"NP_HANDLE_CRC",
|
||||
"NP_HANDLE_PARITY",
|
||||
"NP_ACTIVATE_FIELD",
|
||||
"NP_ACTIVATE_CRYPTO1",
|
||||
"NP_INFINITE_SELECT",
|
||||
"NP_ACCEPT_INVALID_FRAMES",
|
||||
"NP_ACCEPT_MULTIPLE_FRAMES",
|
||||
"NP_AUTO_ISO14443_4",
|
||||
"NP_EASY_FRAMING",
|
||||
"NP_FORCE_ISO14443_A",
|
||||
"NP_FORCE_ISO14443_B",
|
||||
"NP_FORCE_SPEED_106"
|
||||
};
|
||||
|
||||
static void
|
||||
nfc_drivers_init(void)
|
||||
{
|
||||
#if defined (DRIVER_PN53X_USB_ENABLED)
|
||||
nfc_register_driver(&pn53x_usb_driver);
|
||||
#endif /* DRIVER_PN53X_USB_ENABLED */
|
||||
#if defined (DRIVER_PCSC_ENABLED)
|
||||
nfc_register_driver(&pcsc_driver);
|
||||
#endif /* DRIVER_ACR122_PCSC_ENABLED */
|
||||
#if defined (DRIVER_ACR122_PCSC_ENABLED)
|
||||
nfc_register_driver(&acr122_pcsc_driver);
|
||||
#endif /* DRIVER_ACR122_PCSC_ENABLED */
|
||||
@ -156,8 +188,13 @@ nfc_drivers_init(void)
|
||||
#if defined (DRIVER_ARYGON_ENABLED)
|
||||
nfc_register_driver(&arygon_driver);
|
||||
#endif /* DRIVER_ARYGON_ENABLED */
|
||||
#if defined (DRIVER_PN71XX_ENABLED)
|
||||
nfc_register_driver(&pn71xx_driver);
|
||||
#endif /* DRIVER_PN71XX_ENABLED */
|
||||
}
|
||||
|
||||
static int
|
||||
nfc_device_validate_modulation(nfc_device *pnd, const nfc_mode mode, const nfc_modulation *nm);
|
||||
|
||||
/** @ingroup lib
|
||||
* @brief Register an NFC device driver with libnfc.
|
||||
@ -169,8 +206,10 @@ nfc_drivers_init(void)
|
||||
int
|
||||
nfc_register_driver(const struct nfc_driver *ndr)
|
||||
{
|
||||
if (!ndr)
|
||||
if (!ndr) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "nfc_register_driver returning NFC_EINVARG");
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
|
||||
struct nfc_driver_list *pndl = (struct nfc_driver_list *)malloc(sizeof(struct nfc_driver_list));
|
||||
if (!pndl)
|
||||
@ -274,7 +313,7 @@ nfc_open(nfc_context *context, const nfc_connstring connstring)
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Unable to open \"%s\".", ncs);
|
||||
return NULL;
|
||||
}
|
||||
for (uint32_t i = 0; i > context->user_defined_device_count; i++) {
|
||||
for (uint32_t i = 0; i < context->user_defined_device_count; i++) {
|
||||
if (strcmp(ncs, context->user_defined_devices[i].connstring) == 0) {
|
||||
// This is a device sets by user, we use the device name given by user
|
||||
strcpy(pnd->name, context->user_defined_devices[i].name);
|
||||
@ -386,7 +425,7 @@ nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_
|
||||
pndl = pndl->next;
|
||||
}
|
||||
} else if (context->user_defined_device_count == 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "Warning: %s" , "user must specify device(s) manually when autoscan is disabled");
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "Warning: %s", "user must specify device(s) manually when autoscan is disabled");
|
||||
}
|
||||
|
||||
return device_found;
|
||||
@ -406,6 +445,7 @@ nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_
|
||||
int
|
||||
nfc_device_set_property_int(nfc_device *pnd, const nfc_property property, const int value)
|
||||
{
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "set_property_int %s %s", nfc_property_name[property], value ? "True" : "False");
|
||||
HAL(device_set_property_int, pnd, property, value);
|
||||
}
|
||||
|
||||
@ -425,6 +465,7 @@ nfc_device_set_property_int(nfc_device *pnd, const nfc_property property, const
|
||||
int
|
||||
nfc_device_set_property_bool(nfc_device *pnd, const nfc_property property, const bool bEnable)
|
||||
{
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "set_property_bool %s %s", nfc_property_name[property], bEnable ? "True" : "False");
|
||||
HAL(device_set_property_bool, pnd, property, bEnable);
|
||||
}
|
||||
|
||||
@ -480,13 +521,13 @@ nfc_initiator_init(nfc_device *pnd)
|
||||
}
|
||||
|
||||
/** @ingroup initiator
|
||||
* @brief Initialize NFC device as initiator with its secure element initiator (reader)
|
||||
* @brief Initialize NFC device as initiator with its secure element as target (reader)
|
||||
* @return Returns 0 on success, otherwise returns libnfc's error code (negative value)
|
||||
* @param pnd \a nfc_device struct pointer that represent currently used device
|
||||
*
|
||||
* The NFC device is configured to function as secure element reader.
|
||||
* After initialization it can be used to communicate with the secure element.
|
||||
* @note RF field is desactvated in order to some power
|
||||
* @note RF field is deactivated in order to save some power
|
||||
*/
|
||||
int
|
||||
nfc_initiator_init_secure_element(nfc_device *pnd)
|
||||
@ -524,21 +565,30 @@ nfc_initiator_select_passive_target(nfc_device *pnd,
|
||||
nfc_target *pnt)
|
||||
{
|
||||
uint8_t *abtInit = NULL;
|
||||
uint8_t abtTmpInit[MAX(12, szInitData)];
|
||||
uint8_t maxAbt = MAX(12, szInitData);
|
||||
uint8_t *abtTmpInit = malloc(sizeof(uint8_t) * maxAbt);
|
||||
size_t szInit = 0;
|
||||
int res;
|
||||
if ((res = nfc_device_validate_modulation(pnd, N_INITIATOR, &nm)) != NFC_SUCCESS) {
|
||||
free(abtTmpInit);
|
||||
return res;
|
||||
}
|
||||
if (szInitData == 0) {
|
||||
// Provide default values, if any
|
||||
prepare_initiator_data(nm, &abtInit, &szInit);
|
||||
free(abtTmpInit);
|
||||
} else if (nm.nmt == NMT_ISO14443A) {
|
||||
abtInit = abtTmpInit;
|
||||
iso14443_cascade_uid(pbtInitData, szInitData, abtInit, &szInit);
|
||||
} else {
|
||||
abtInit = abtTmpInit;
|
||||
memcpy(abtInit, pbtInitData, szInitData);
|
||||
free(abtTmpInit);
|
||||
szInit = szInitData;
|
||||
}
|
||||
|
||||
HAL(initiator_select_passive_target, pnd, nm, abtInit, szInit, pnt);
|
||||
|
||||
free(abtTmpInit);
|
||||
}
|
||||
|
||||
/** @ingroup initiator
|
||||
@ -596,9 +646,10 @@ nfc_initiator_list_passive_targets(nfc_device *pnd,
|
||||
break;
|
||||
}
|
||||
nfc_initiator_deselect_target(pnd);
|
||||
// deselect has no effect on FeliCa and Jewel cards so we'll stop after one...
|
||||
// deselect has no effect on FeliCa, Jewel and Thinfilm cards so we'll stop after one...
|
||||
// ISO/IEC 14443 B' cards are polled at 100% probability so it's not possible to detect correctly two cards at the same time
|
||||
if ((nm.nmt == NMT_FELICA) || (nm.nmt == NMT_JEWEL) || (nm.nmt == NMT_ISO14443BI) || (nm.nmt == NMT_ISO14443B2SR) || (nm.nmt == NMT_ISO14443B2CT)) {
|
||||
if ((nm.nmt == NMT_FELICA) || (nm.nmt == NMT_JEWEL) || (nm.nmt == NMT_BARCODE) ||
|
||||
(nm.nmt == NMT_ISO14443BI) || (nm.nmt == NMT_ISO14443B2SR) || (nm.nmt == NMT_ISO14443B2CT)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -640,7 +691,7 @@ nfc_initiator_poll_target(nfc_device *pnd,
|
||||
* @param pnd \a nfc_device struct pointer that represent currently used device
|
||||
* @param ndm desired D.E.P. mode (\a NDM_ACTIVE or \a NDM_PASSIVE for active, respectively passive mode)
|
||||
* @param nbr desired baud rate
|
||||
* @param ndiInitiator pointer \a nfc_dep_info struct that contains \e NFCID3 and \e General \e Bytes to set to the initiator device (optionnal, can be \e NULL)
|
||||
* @param pndiInitiator pointer \a nfc_dep_info struct that contains \e NFCID3 and \e General \e Bytes to set to the initiator device (optionnal, can be \e NULL)
|
||||
* @param[out] pnt is a \a nfc_target struct pointer where target information will be put.
|
||||
* @param timeout in milliseconds
|
||||
*
|
||||
@ -668,7 +719,7 @@ nfc_initiator_select_dep_target(nfc_device *pnd,
|
||||
* @param pnd \a nfc_device struct pointer that represent currently used device
|
||||
* @param ndm desired D.E.P. mode (\a NDM_ACTIVE or \a NDM_PASSIVE for active, respectively passive mode)
|
||||
* @param nbr desired baud rate
|
||||
* @param ndiInitiator pointer \a nfc_dep_info struct that contains \e NFCID3 and \e General \e Bytes to set to the initiator device (optionnal, can be \e NULL)
|
||||
* @param pndiInitiator pointer \a nfc_dep_info struct that contains \e NFCID3 and \e General \e Bytes to set to the initiator device (optionnal, can be \e NULL)
|
||||
* @param[out] pnt is a \a nfc_target struct pointer where target information will be put.
|
||||
* @param timeout in milliseconds
|
||||
*
|
||||
@ -967,7 +1018,7 @@ nfc_target_init(nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t s
|
||||
* @param pnd \a nfc_device struct pointer that represent currently used device
|
||||
*
|
||||
* This function switch the device in idle mode.
|
||||
* In initiator mode, the RF field is turned off and the device is set to low power mode (if avaible);
|
||||
* In initiator mode, the RF field is turned off and the device is set to low power mode (if available);
|
||||
* In target mode, the emulation is stoped (no target available from external initiator) and the device is set to low power mode (if avaible).
|
||||
*/
|
||||
int
|
||||
@ -1193,7 +1244,7 @@ nfc_device_get_supported_modulation(nfc_device *pnd, const nfc_mode mode, const
|
||||
}
|
||||
|
||||
/** @ingroup data
|
||||
* @brief Get supported baud rates.
|
||||
* @brief Get supported baud rates (initiator mode).
|
||||
* @return Returns 0 on success, otherwise returns libnfc's error code (negative value)
|
||||
* @param pnd \a nfc_device struct pointer that represent currently used device
|
||||
* @param nmt \a nfc_modulation_type.
|
||||
@ -1203,7 +1254,63 @@ nfc_device_get_supported_modulation(nfc_device *pnd, const nfc_mode mode, const
|
||||
int
|
||||
nfc_device_get_supported_baud_rate(nfc_device *pnd, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br)
|
||||
{
|
||||
HAL(get_supported_baud_rate, pnd, nmt, supported_br);
|
||||
HAL(get_supported_baud_rate, pnd, N_INITIATOR, nmt, supported_br);
|
||||
}
|
||||
|
||||
/** @ingroup data
|
||||
* @brief Get supported baud rates for target mode.
|
||||
* @return Returns 0 on success, otherwise returns libnfc's error code (negative value)
|
||||
* @param pnd \a nfc_device struct pointer that represent currently used device
|
||||
* @param nmt \a nfc_modulation_type.
|
||||
* @param supported_br pointer of \a nfc_baud_rate array.
|
||||
*
|
||||
*/
|
||||
int
|
||||
nfc_device_get_supported_baud_rate_target_mode(nfc_device *pnd, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br)
|
||||
{
|
||||
HAL(get_supported_baud_rate, pnd, N_TARGET, nmt, supported_br);
|
||||
}
|
||||
|
||||
/** @ingroup data
|
||||
* @brief Validate combination of modulation and baud rate on the currently used device.
|
||||
* @return Returns 0 on success, otherwise returns libnfc's error code (negative value)
|
||||
* @param pnd \a nfc_device struct pointer that represent currently used device
|
||||
* @param mode \a nfc_mode.
|
||||
* @param nm \a nfc_modulation.
|
||||
*
|
||||
*/
|
||||
static int
|
||||
nfc_device_validate_modulation(nfc_device *pnd, const nfc_mode mode, const nfc_modulation *nm)
|
||||
{
|
||||
int res;
|
||||
const nfc_modulation_type *nmt = NULL;
|
||||
if ((res = nfc_device_get_supported_modulation(pnd, mode, &nmt)) < 0) {
|
||||
return res;
|
||||
}
|
||||
assert(nmt != NULL);
|
||||
for (int i = 0; nmt[i]; i++) {
|
||||
if (nmt[i] == nm->nmt) {
|
||||
const nfc_baud_rate *nbr = NULL;
|
||||
if (mode == N_INITIATOR) {
|
||||
if ((res = nfc_device_get_supported_baud_rate(pnd, nmt[i], &nbr)) < 0) {
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
if ((res = nfc_device_get_supported_baud_rate_target_mode(pnd, nmt[i], &nbr)) < 0) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
assert(nbr != NULL);
|
||||
for (int j = 0; nbr[j]; j++) {
|
||||
if (nbr[j] == nm->nbr)
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "nfc_device_validate_modulation returning NFC_EINVARG");
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
}
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "nfc_device_validate_modulation returning NFC_EINVARG");
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
|
||||
/* Misc. functions */
|
||||
@ -1252,7 +1359,7 @@ nfc_device_get_information_about(nfc_device *pnd, char **buf)
|
||||
/** @ingroup string-converter
|
||||
* @brief Convert \a nfc_baud_rate value to string
|
||||
* @return Returns nfc baud rate
|
||||
* @param \a nfc_baud_rate to convert
|
||||
* @param nbr \a nfc_baud_rate to convert
|
||||
*/
|
||||
const char *
|
||||
str_nfc_baud_rate(const nfc_baud_rate nbr)
|
||||
@ -1260,28 +1367,23 @@ str_nfc_baud_rate(const nfc_baud_rate nbr)
|
||||
switch (nbr) {
|
||||
case NBR_UNDEFINED:
|
||||
return "undefined baud rate";
|
||||
break;
|
||||
case NBR_106:
|
||||
return "106 kbps";
|
||||
break;
|
||||
case NBR_212:
|
||||
return "212 kbps";
|
||||
break;
|
||||
case NBR_424:
|
||||
return "424 kbps";
|
||||
break;
|
||||
case NBR_847:
|
||||
return "847 kbps";
|
||||
break;
|
||||
}
|
||||
// Should never go there..
|
||||
return "";
|
||||
|
||||
return "???";
|
||||
}
|
||||
|
||||
/** @ingroup string-converter
|
||||
* @brief Convert \a nfc_modulation_type value to string
|
||||
* @return Returns nfc modulation type
|
||||
* @param \a nfc_modulation_type to convert
|
||||
* @param nmt \a nfc_modulation_type to convert
|
||||
*/
|
||||
const char *
|
||||
str_nfc_modulation_type(const nfc_modulation_type nmt)
|
||||
@ -1289,38 +1391,35 @@ str_nfc_modulation_type(const nfc_modulation_type nmt)
|
||||
switch (nmt) {
|
||||
case NMT_ISO14443A:
|
||||
return "ISO/IEC 14443A";
|
||||
break;
|
||||
case NMT_ISO14443B:
|
||||
return "ISO/IEC 14443-4B";
|
||||
break;
|
||||
case NMT_ISO14443BI:
|
||||
return "ISO/IEC 14443-4B'";
|
||||
break;
|
||||
case NMT_ISO14443BICLASS:
|
||||
return "ISO/IEC 14443-2B-3B iClass (Picopass)";
|
||||
case NMT_ISO14443B2CT:
|
||||
return "ISO/IEC 14443-2B ASK CTx";
|
||||
break;
|
||||
case NMT_ISO14443B2SR:
|
||||
return "ISO/IEC 14443-2B ST SRx";
|
||||
break;
|
||||
case NMT_FELICA:
|
||||
return "FeliCa";
|
||||
break;
|
||||
case NMT_JEWEL:
|
||||
return "Innovision Jewel";
|
||||
break;
|
||||
case NMT_BARCODE:
|
||||
return "Thinfilm NFC Barcode";
|
||||
case NMT_DEP:
|
||||
return "D.E.P.";
|
||||
break;
|
||||
}
|
||||
// Should never go there..
|
||||
return "";
|
||||
|
||||
return "???";
|
||||
}
|
||||
|
||||
/** @ingroup string-converter
|
||||
* @brief Convert \a nfc_modulation_type value to string
|
||||
* @brief Convert \a nfc_target content to string
|
||||
* @return Upon successful return, this function returns the number of characters printed (excluding the null byte used to end output to strings), otherwise returns libnfc's error code (negative value)
|
||||
* @param nt \a nfc_target struct to print
|
||||
* @param pnt \a nfc_target struct pointer to print
|
||||
* @param buf pointer where string will be allocated, then nfc target information printed
|
||||
* @param verbose false for essential, true for detailed, human-readable, information
|
||||
*
|
||||
* @warning *buf must be freed using nfc_free()
|
||||
*/
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||
* See AUTHORS file for a more comprehensive list of contributors.
|
||||
* Additional contributors of this file:
|
||||
* Copyright (C) 2020 Adam Laurie
|
||||
*
|
||||
* 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
|
||||
@ -498,6 +499,22 @@ snprint_nfc_jewel_info(char *dst, size_t size, const nfc_jewel_info *pnji, bool
|
||||
snprint_hex(dst + off, size - off, pnji->btId, 4);
|
||||
}
|
||||
|
||||
void
|
||||
snprint_nfc_barcode_info(char *dst, size_t size, const nfc_barcode_info *pnti, bool verbose)
|
||||
{
|
||||
(void) verbose;
|
||||
int off = 0;
|
||||
off += snprintf(dst + off, size - off, " Size (bits): %lu\n", (unsigned long)(pnti->szDataLen * 8));
|
||||
off += snprintf(dst + off, size - off, " Content: ");
|
||||
for (uint8_t i = 0; i < pnti->szDataLen; i++) {
|
||||
off += snprintf(dst + off, size - off, "%02X", pnti->abtData[i]);
|
||||
if ((i % 8 == 7) && (i < (pnti->szDataLen - 1))) {
|
||||
off += snprintf(dst + off, size - off, "\n ");
|
||||
}
|
||||
}
|
||||
snprintf(dst + off, size - off, "\n");
|
||||
}
|
||||
|
||||
#define PI_ISO14443_4_SUPPORTED 0x01
|
||||
#define PI_NAD_SUPPORTED 0x01
|
||||
#define PI_CID_SUPPORTED 0x02
|
||||
@ -593,6 +610,15 @@ snprint_nfc_iso14443b2sr_info(char *dst, size_t size, const nfc_iso14443b2sr_inf
|
||||
snprint_hex(dst + off, size - off, pnsi->abtUID, 8);
|
||||
}
|
||||
|
||||
void
|
||||
snprint_nfc_iso14443biclass_info(char *dst, size_t size, const nfc_iso14443biclass_info *pnic, bool verbose)
|
||||
{
|
||||
(void) verbose;
|
||||
int off = 0;
|
||||
off += snprintf(dst + off, size - off, " UID: ");
|
||||
snprint_hex(dst + off, size - off, pnic->abtUID, 8);
|
||||
}
|
||||
|
||||
void
|
||||
snprint_nfc_iso14443b2ct_info(char *dst, size_t size, const nfc_iso14443b2ct_info *pnci, bool verbose)
|
||||
{
|
||||
@ -637,6 +663,9 @@ snprint_nfc_target(char *dst, size_t size, const nfc_target *pnt, bool verbose)
|
||||
case NMT_JEWEL:
|
||||
snprint_nfc_jewel_info(dst + off, size - off, &pnt->nti.nji, verbose);
|
||||
break;
|
||||
case NMT_BARCODE:
|
||||
snprint_nfc_barcode_info(dst + off, size - off, &pnt->nti.nti, verbose);
|
||||
break;
|
||||
case NMT_FELICA:
|
||||
snprint_nfc_felica_info(dst + off, size - off, &pnt->nti.nfi, verbose);
|
||||
break;
|
||||
@ -649,6 +678,9 @@ snprint_nfc_target(char *dst, size_t size, const nfc_target *pnt, bool verbose)
|
||||
case NMT_ISO14443B2SR:
|
||||
snprint_nfc_iso14443b2sr_info(dst + off, size - off, &pnt->nti.nsi, verbose);
|
||||
break;
|
||||
case NMT_ISO14443BICLASS:
|
||||
snprint_nfc_iso14443biclass_info(dst + off, size - off, &pnt->nti.nhi, verbose);
|
||||
break;
|
||||
case NMT_ISO14443B2CT:
|
||||
snprint_nfc_iso14443b2ct_info(dst + off, size - off, &pnt->nti.nci, verbose);
|
||||
break;
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||
* See AUTHORS file for a more comprehensive list of contributors.
|
||||
* Additional contributors of this file:
|
||||
* Copyright (C) 2020 Adam Laurie
|
||||
*
|
||||
* 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
|
||||
@ -37,9 +38,11 @@ void snprint_nfc_iso14443a_info(char *dst, size_t size, const nfc_iso14443a_i
|
||||
void snprint_nfc_iso14443b_info(char *dst, size_t size, const nfc_iso14443b_info *pnbi, bool verbose);
|
||||
void snprint_nfc_iso14443bi_info(char *dst, size_t size, const nfc_iso14443bi_info *pnii, bool verbose);
|
||||
void snprint_nfc_iso14443b2sr_info(char *dst, size_t size, const nfc_iso14443b2sr_info *pnsi, bool verbose);
|
||||
void snprint_nfc_iso14443biclass_info(char *dst, size_t size, const nfc_iso14443biclass_info *pnic, bool verbose);
|
||||
void snprint_nfc_iso14443b2ct_info(char *dst, size_t size, const nfc_iso14443b2ct_info *pnci, bool verbose);
|
||||
void snprint_nfc_felica_info(char *dst, size_t size, const nfc_felica_info *pnfi, bool verbose);
|
||||
void snprint_nfc_jewel_info(char *dst, size_t size, const nfc_jewel_info *pnji, bool verbose);
|
||||
void snprint_nfc_barcode_info(char *dst, size_t size, const nfc_barcode_info *pnti, bool verbose);
|
||||
void snprint_nfc_dep_info(char *dst, size_t size, const nfc_dep_info *pndi, bool verbose);
|
||||
void snprint_nfc_target(char *dst, size_t size, const nfc_target *pnt, bool verbose);
|
||||
|
||||
|
||||
@ -4,7 +4,8 @@ AC_DEFUN([LIBNFC_ARG_WITH_DRIVERS],
|
||||
[
|
||||
AC_MSG_CHECKING(which drivers to build)
|
||||
AC_ARG_WITH(drivers,
|
||||
AS_HELP_STRING([--with-drivers=DRIVERS], [Use a custom driver set, where DRIVERS is a coma-separated list of drivers to build support for. Available drivers are: 'acr122_pcsc', 'acr122_usb', 'acr122s', 'arygon', 'pn532_i2c', 'pn532_spi', 'pn532_uart' and 'pn53x_usb'. Default drivers set is 'acr122_usb,acr122s,arygon,pn532_i2c,pn532_spi,pn532_uart,pn53x_usb'. The special driver set 'all' compile all available drivers.]),
|
||||
AS_HELP_STRING([--with-drivers=DRIVERS], [Use a custom driver set, where DRIVERS is a coma-separated list of drivers to build support for. Available drivers are: 'acr122_pcsc', 'acr122_usb', 'acr122s', 'arygon', 'pcsc', 'pn532_i2c', 'pn532_spi', 'pn532_uart', 'pn53x_usb' and 'pn71xx'. Default drivers set is 'acr122_usb,acr122s,arygon,pn532_i2c,pn532_spi,pn532_uart,pn53x_usb'. The special driver set 'all' compile all available drivers.]),
|
||||
|
||||
[ case "${withval}" in
|
||||
yes | no)
|
||||
dnl ignore calls without any arguments
|
||||
@ -36,7 +37,8 @@ AC_DEFUN([LIBNFC_ARG_WITH_DRIVERS],
|
||||
fi
|
||||
;;
|
||||
all)
|
||||
DRIVER_BUILD_LIST="acr122_pcsc acr122_usb acr122s arygon pn53x_usb pn532_uart"
|
||||
DRIVER_BUILD_LIST="acr122_pcsc acr122_usb acr122s arygon pn53x_usb pn532_uart pcsc"
|
||||
|
||||
if test x"$spi_available" = x"yes"
|
||||
then
|
||||
DRIVER_BUILD_LIST="$DRIVER_BUILD_LIST pn532_spi"
|
||||
@ -45,11 +47,16 @@ AC_DEFUN([LIBNFC_ARG_WITH_DRIVERS],
|
||||
then
|
||||
DRIVER_BUILD_LIST="$DRIVER_BUILD_LIST pn532_i2c"
|
||||
fi
|
||||
if test x"$nfc_nci_available" = x"yes"
|
||||
then
|
||||
DRIVER_BUILD_LIST="$DRIVER_BUILD_LIST pn71xx"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
DRIVERS_CFLAGS=""
|
||||
|
||||
driver_pcsc_enabled="no"
|
||||
driver_acr122_pcsc_enabled="no"
|
||||
driver_acr122_usb_enabled="no"
|
||||
driver_acr122s_enabled="no"
|
||||
@ -58,10 +65,16 @@ AC_DEFUN([LIBNFC_ARG_WITH_DRIVERS],
|
||||
driver_pn532_uart_enabled="no"
|
||||
driver_pn532_spi_enabled="no"
|
||||
driver_pn532_i2c_enabled="no"
|
||||
driver_pn71xx_enabled="no"
|
||||
|
||||
for driver in ${DRIVER_BUILD_LIST}
|
||||
do
|
||||
case "${driver}" in
|
||||
pcsc)
|
||||
pcsc_required="yes"
|
||||
driver_pcsc_enabled="yes"
|
||||
DRIVERS_CFLAGS="$DRIVERS_CFLAGS -DDRIVER_PCSC_ENABLED"
|
||||
;;
|
||||
acr122_pcsc)
|
||||
pcsc_required="yes"
|
||||
driver_acr122_pcsc_enabled="yes"
|
||||
@ -102,6 +115,11 @@ AC_DEFUN([LIBNFC_ARG_WITH_DRIVERS],
|
||||
driver_pn532_i2c_enabled="yes"
|
||||
DRIVERS_CFLAGS="$DRIVERS_CFLAGS -DDRIVER_PN532_I2C_ENABLED"
|
||||
;;
|
||||
pn71xx)
|
||||
nfc_nci_required="yes"
|
||||
driver_pn71xx_enabled="yes"
|
||||
DRIVERS_CFLAGS="$DRIVERS_CFLAGS -DDRIVER_PN71XX_ENABLED"
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Unknow driver: $driver])
|
||||
;;
|
||||
@ -109,6 +127,7 @@ AC_DEFUN([LIBNFC_ARG_WITH_DRIVERS],
|
||||
done
|
||||
AC_SUBST(DRIVERS_CFLAGS)
|
||||
AM_CONDITIONAL(DRIVER_ACR122_PCSC_ENABLED, [test x"$driver_acr122_pcsc_enabled" = xyes])
|
||||
AM_CONDITIONAL(DRIVER_PCSC_ENABLED, [test x"$driver_pcsc_enabled" = xyes])
|
||||
AM_CONDITIONAL(DRIVER_ACR122_USB_ENABLED, [test x"$driver_acr122_usb_enabled" = xyes])
|
||||
AM_CONDITIONAL(DRIVER_ACR122S_ENABLED, [test x"$driver_acr122s_enabled" = xyes])
|
||||
AM_CONDITIONAL(DRIVER_PN53X_USB_ENABLED, [test x"$driver_pn53x_usb_enabled" = xyes])
|
||||
@ -116,11 +135,13 @@ AC_DEFUN([LIBNFC_ARG_WITH_DRIVERS],
|
||||
AM_CONDITIONAL(DRIVER_PN532_UART_ENABLED, [test x"$driver_pn532_uart_enabled" = xyes])
|
||||
AM_CONDITIONAL(DRIVER_PN532_SPI_ENABLED, [test x"$driver_pn532_spi_enabled" = xyes])
|
||||
AM_CONDITIONAL(DRIVER_PN532_I2C_ENABLED, [test x"$driver_pn532_i2c_enabled" = xyes])
|
||||
AM_CONDITIONAL(DRIVER_PN71XX_ENABLED, [test x"$driver_pn71xx_enabled" = xyes])
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBNFC_DRIVERS_SUMMARY],[
|
||||
echo
|
||||
echo "Selected drivers:"
|
||||
echo " pcsc............. $driver_pcsc_enabled"
|
||||
echo " acr122_pcsc...... $driver_acr122_pcsc_enabled"
|
||||
echo " acr122_usb....... $driver_acr122_usb_enabled"
|
||||
echo " acr122s.......... $driver_acr122s_enabled"
|
||||
@ -129,4 +150,5 @@ echo " pn53x_usb........ $driver_pn53x_usb_enabled"
|
||||
echo " pn532_uart....... $driver_pn532_uart_enabled"
|
||||
echo " pn532_spi....... $driver_pn532_spi_enabled"
|
||||
echo " pn532_i2c........ $driver_pn532_i2c_enabled"
|
||||
echo " pn71xx........... $driver_pn71xx_enabled"
|
||||
])
|
||||
|
||||
34
mingw-cross-compile.sh
Normal file
34
mingw-cross-compile.sh
Normal file
@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
PROJECT_DIR=$(readlink -e $(dirname $0))
|
||||
cd "$PROJECT_DIR"
|
||||
|
||||
WITH_USB=1
|
||||
|
||||
LIBUSB_WIN32_BIN_VERSION="1.2.6.0"
|
||||
LIBUSB_WIN32_BIN_ARCHIVE="libusb-win32-bin-$LIBUSB_WIN32_BIN_VERSION.zip"
|
||||
LIBUSB_WIN32_BIN_URL="http://freefr.dl.sourceforge.net/project/libusb-win32/libusb-win32-releases/$LIBUSB_WIN32_BIN_VERSION/$LIBUSB_WIN32_BIN_ARCHIVE"
|
||||
LIBUSB_WIN32_BIN_DIR="libusb-win32-bin-$LIBUSB_WIN32_BIN_VERSION"
|
||||
|
||||
if [ "$WITH_USB" = "1" ]; then
|
||||
if [ ! -d $LIBUSB_WIN32_BIN_DIR ]; then
|
||||
wget -c $LIBUSB_WIN32_BIN_URL
|
||||
unzip $LIBUSB_WIN32_BIN_ARCHIVE
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
|
||||
case $1 in
|
||||
32*)
|
||||
mingw32-cmake .. -DLIBUSB_INCLUDE_DIRS="$PROJECT_DIR"/libusb-win32-bin-1.2.6.0/include -DLIBUSB_LIBRARIES="$PROJECT_DIR"/libusb-win32-bin-1.2.6.0/bin/x86/libusb0_x86.dll -DLIBNFC_ROOT_DIR=$PWD/.. -DLIBNFC_SYSCONFDIR='C:\\Program Files (x86)\\libnfc\\config'
|
||||
mingw32-make;;
|
||||
64*)
|
||||
mingw64-cmake .. -DLIBUSB_INCLUDE_DIRS="$PROJECT_DIR"/libusb-win32-bin-1.2.6.0/include -DLIBUSB_LIBRARIES="$PROJECT_DIR"/libusb-win32-bin-1.2.6.0/bin/amd64/libusb0.dll -DLIBNFC_ROOT_DIR=.. -DLIBNFC_SYSCONFDIR='C:\\Program Files\\libnfc\\config'
|
||||
mingw64-make;;
|
||||
*)
|
||||
echo "specify whether to build 32-bit or 64-bit version by supplying 32 or 64 as parameter";;
|
||||
esac
|
||||
@ -1,91 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
WITH_USB=1
|
||||
|
||||
LIBUSB_WIN32_BIN_VERSION="1.2.6.0"
|
||||
LIBUSB_WIN32_BIN_ARCHIVE="libusb-win32-bin-$LIBUSB_WIN32_BIN_VERSION.zip"
|
||||
LIBUSB_WIN32_BIN_URL="http://freefr.dl.sourceforge.net/project/libusb-win32/libusb-win32-releases/$LIBUSB_WIN32_BIN_VERSION/$LIBUSB_WIN32_BIN_ARCHIVE"
|
||||
LIBUSB_WIN32_BIN_DIR="libusb-win32-bin-$LIBUSB_WIN32_BIN_VERSION"
|
||||
|
||||
if [ "$WITH_USB" = "1" ]; then
|
||||
if [ ! -d $LIBUSB_WIN32_BIN_DIR ]; then
|
||||
wget -c $LIBUSB_WIN32_BIN_URL
|
||||
unzip $LIBUSB_WIN32_BIN_ARCHIVE
|
||||
fi
|
||||
fi
|
||||
|
||||
MINGW="${MINGW:=i686-w64-mingw32}"
|
||||
MINGW_DIR="/usr/$MINGW"
|
||||
|
||||
# Use MinGW binaries before others
|
||||
#export PATH=$MINGW_DIR/bin:$PATH
|
||||
|
||||
# Set CPATH to MinGW include files
|
||||
export CPATH=$MINGW_DIR/include
|
||||
export LD_LIBRARY_PATH=$MINGW_DIR/lib
|
||||
export LD_RUN_PATH=$MINGW_DIR/lib
|
||||
|
||||
# Force pkg-config to search in cross environement directory
|
||||
export PKG_CONFIG_LIBDIR=$MINGW_DIR/lib/pkgconfig
|
||||
|
||||
# Stop compilation on first error
|
||||
export CFLAGS="-Wfatal-errors"
|
||||
|
||||
# Include default MinGW include directory, and libnfc's win32 files
|
||||
export CFLAGS="$CFLAGS -I$MINGW_DIR/include -I$PWD/contrib/win32"
|
||||
|
||||
if [ "$MINGW" = "i686-w64-mingw32" ]; then
|
||||
# mingw-64 includes winscard.a and winscard.h
|
||||
#
|
||||
# It is not enough to set libpcsclite_LIBS to "-lwinscard", because it is
|
||||
# forgotten when libnfc is created with libtool. That's why we are setting
|
||||
# LIBS.
|
||||
export LIBS="-lwinscard"
|
||||
|
||||
echo "MinGW-w64 ships all requirements libnfc."
|
||||
echo "Unfortunately the MinGW-w64 header are currently"
|
||||
echo "buggy. Also, Libtool doesn't support MinGW-w64"
|
||||
echo "very well."
|
||||
echo ""
|
||||
echo "Warning ________________________________________"
|
||||
echo "You will only be able to compile libnfc.dll, but"
|
||||
echo "none of the executables (see utils and examples)."
|
||||
echo ""
|
||||
# You can fix winbase.h by adding the following lines:
|
||||
# #include <basetsd.h>
|
||||
# #include <windef.h>
|
||||
# But the problem with Libtool remains.
|
||||
else
|
||||
if [ -z "$libpcsclite_LIBS$libpcsclite_CFLAGS" ]; then
|
||||
echo "Error __________________________________________"
|
||||
echo "You need to get the PC/SC library from a Windows"
|
||||
echo "machine and the appropriate header files. Then"
|
||||
echo "specify libpcsclite_LIBS=.../WinScard.dll and"
|
||||
echo "libpcsclite_CFLAGS=-I..."
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## Configure to cross-compile using mingw32msvc
|
||||
if [ "$WITH_USB" = "1" ]; then
|
||||
# with direct-USB drivers (use libusb-win32)
|
||||
DRIVERS="all"
|
||||
else
|
||||
# with UART divers only (can be tested under wine)
|
||||
DRIVERS="pn532_uart,arygon"
|
||||
fi
|
||||
|
||||
if [ ! -x configure ]; then
|
||||
autoreconf -is
|
||||
fi
|
||||
|
||||
./configure --target=$MINGW --host=$MINGW \
|
||||
--with-drivers=$DRIVERS \
|
||||
--with-libusb-win32=$PWD/$LIBUSB_WIN32_BIN_DIR \
|
||||
$*
|
||||
|
||||
if [ "$MINGW" = "i686-w64-mingw32" ]; then
|
||||
# due to the buggy headers from MINGW-64 we always add "contrib/windows.h",
|
||||
# otherwise some windows types won't be available.
|
||||
echo "#include \"contrib/windows.h\"" >> config.h
|
||||
fi
|
||||
@ -45,7 +45,7 @@ test_register_endianness_la_LIBADD = $(top_builddir)/libnfc/libnfc.la
|
||||
echo-cutter:
|
||||
@echo $(CUTTER)
|
||||
|
||||
EXTRA_DIST = run-test.sh
|
||||
CLEANFILES = *.gcno
|
||||
|
||||
endif
|
||||
EXTRA_DIST = run-test.sh
|
||||
|
||||
@ -45,7 +45,7 @@ test_access_storm(void)
|
||||
.nbr = NBR_106,
|
||||
};
|
||||
res = nfc_initiator_list_passive_targets(device, nm, ant, MAX_TARGET_COUNT);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("nfc_initiator_list_passive_targets"));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("nfc_initiator_list_passive_targets"));
|
||||
|
||||
nfc_close(device);
|
||||
}
|
||||
|
||||
@ -86,18 +86,18 @@ target_thread(void *arg)
|
||||
|
||||
uint8_t abtRx[1024];
|
||||
int res = nfc_target_init(device, &nt, abtRx, sizeof(abtRx), 0);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't initialize NFC device as target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't initialize NFC device as target: %s", nfc_strerror(device)));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
res = nfc_target_receive_bytes(device, abtRx, sizeof(abtRx), 500);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
|
||||
const uint8_t abtAttRx[] = "Hello DEP target!";
|
||||
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
|
||||
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
const uint8_t abtTx[] = "Hello DEP initiator!";
|
||||
res = nfc_target_send_bytes(device, abtTx, sizeof(abtTx), 500);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't send bytes to initiator: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't send bytes to initiator: %s", nfc_strerror(device)));
|
||||
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
return (void *) thread_res;
|
||||
@ -125,7 +125,7 @@ initiator_thread(void *arg)
|
||||
// Active mode
|
||||
printf("=========== INITIATOR %s (Active mode / %s Kbps) =========\n", nfc_device_get_name(device), str_nfc_baud_rate(nbr));
|
||||
res = nfc_initiator_select_dep_target(device, NDM_ACTIVE, nbr, NULL, &nt, 1000);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't select any DEP target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't select any DEP target: %s", nfc_strerror(device)));
|
||||
cut_assert_equal_int(NMT_DEP, nt.nm.nmt, cut_message("Invalid target modulation"));
|
||||
cut_assert_equal_int(nbr, nt.nm.nbr, cut_message("Invalid target baud rate"));
|
||||
cut_assert_equal_memory("\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA", 10, nt.nti.ndi.abtNFCID3, 10, cut_message("Invalid target NFCID3"));
|
||||
@ -136,13 +136,13 @@ initiator_thread(void *arg)
|
||||
const uint8_t abtTx[] = "Hello DEP target!";
|
||||
uint8_t abtRx[1024];
|
||||
res = nfc_initiator_transceive_bytes(device, abtTx, sizeof(abtTx), abtRx, sizeof(abtRx), 5000);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("Can't transceive bytes to target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("Can't transceive bytes to target: %s", nfc_strerror(device)));
|
||||
|
||||
const uint8_t abtAttRx[] = "Hello DEP initiator!";
|
||||
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data (as initiator)"));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
res = nfc_initiator_deselect_target(device);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("Can't deselect target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("Can't deselect target: %s", nfc_strerror(device)));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
return (void *) thread_res;
|
||||
|
||||
@ -86,12 +86,12 @@ target_thread(void *arg)
|
||||
uint8_t abtRx[1024];
|
||||
size_t szRx = sizeof(abtRx);
|
||||
int res = nfc_target_init(device, &nt, abtRx, szRx, 0);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't initialize NFC device as target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't initialize NFC device as target: %s", nfc_strerror(device)));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
// First pass
|
||||
res = nfc_target_receive_bytes(device, abtRx, sizeof(abtRx), 500);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
|
||||
|
||||
const uint8_t abtAttRx[] = "Hello DEP target!";
|
||||
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
|
||||
@ -99,40 +99,40 @@ target_thread(void *arg)
|
||||
|
||||
const uint8_t abtTx[] = "Hello DEP initiator!";
|
||||
res = nfc_target_send_bytes(device, abtTx, sizeof(abtTx), 500);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't send bytes to initiator: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't send bytes to initiator: %s", nfc_strerror(device)));
|
||||
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
// Second pass
|
||||
res = nfc_target_receive_bytes(device, abtRx, sizeof(abtRx), 500);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
|
||||
|
||||
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
|
||||
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
res = nfc_target_send_bytes(device, abtTx, sizeof(abtTx), 500);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't send bytes to initiator: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't send bytes to initiator: %s", nfc_strerror(device)));
|
||||
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
// Third pass
|
||||
res = nfc_target_receive_bytes(device, abtRx, sizeof(abtRx), 500);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
|
||||
|
||||
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
|
||||
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
res = nfc_target_send_bytes(device, abtTx, sizeof(abtTx), 500);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't send bytes to initiator: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't send bytes to initiator: %s", nfc_strerror(device)));
|
||||
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
// Fourth pass
|
||||
res = nfc_target_receive_bytes(device, abtRx, sizeof(abtRx), 500);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
|
||||
|
||||
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
|
||||
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
res = nfc_target_send_bytes(device, abtTx, sizeof(abtTx), 500);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't send bytes to initiator: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't send bytes to initiator: %s", nfc_strerror(device)));
|
||||
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
return (void *) thread_res;
|
||||
@ -160,7 +160,7 @@ initiator_thread(void *arg)
|
||||
// Passive mode / 106Kbps
|
||||
printf("=========== INITIATOR %s (Passive mode / 106Kbps) =========\n", nfc_device_get_name(device));
|
||||
res = nfc_initiator_select_dep_target(device, NDM_PASSIVE, NBR_106, NULL, &nt, 5000);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't select any DEP target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't select any DEP target: %s", nfc_strerror(device)));
|
||||
cut_assert_equal_int(NMT_DEP, nt.nm.nmt, cut_message("Invalid target modulation"));
|
||||
cut_assert_equal_int(NBR_106, nt.nm.nbr, cut_message("Invalid target baud rate"));
|
||||
cut_assert_equal_memory("\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA", 10, nt.nti.ndi.abtNFCID3, 10, cut_message("Invalid target NFCID3"));
|
||||
@ -171,20 +171,20 @@ initiator_thread(void *arg)
|
||||
const uint8_t abtTx[] = "Hello DEP target!";
|
||||
uint8_t abtRx[1024];
|
||||
res = nfc_initiator_transceive_bytes(device, abtTx, sizeof(abtTx), abtRx, sizeof(abtRx), 500);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("Can't transceive bytes to target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("Can't transceive bytes to target: %s", nfc_strerror(device)));
|
||||
|
||||
const uint8_t abtAttRx[] = "Hello DEP initiator!";
|
||||
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
res = nfc_initiator_deselect_target(device);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("Can't deselect target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("Can't deselect target: %s", nfc_strerror(device)));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
// Passive mode / 212Kbps (second pass)
|
||||
printf("=========== INITIATOR %s (Passive mode / 212Kbps) =========\n", nfc_device_get_name(device));
|
||||
res = nfc_initiator_select_dep_target(device, NDM_PASSIVE, NBR_212, NULL, &nt, 1000);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't select any DEP target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't select any DEP target: %s", nfc_strerror(device)));
|
||||
cut_assert_equal_int(NMT_DEP, nt.nm.nmt, cut_message("Invalid target modulation"));
|
||||
cut_assert_equal_int(NBR_212, nt.nm.nbr, cut_message("Invalid target baud rate"));
|
||||
cut_assert_equal_memory("\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA", 10, nt.nti.ndi.abtNFCID3, 10, cut_message("Invalid target NFCID3"));
|
||||
@ -193,19 +193,19 @@ initiator_thread(void *arg)
|
||||
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
res = nfc_initiator_transceive_bytes(device, abtTx, sizeof(abtTx), abtRx, sizeof(abtRx), 1000);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("Can't transceive bytes to target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("Can't transceive bytes to target: %s", nfc_strerror(device)));
|
||||
|
||||
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
res = nfc_initiator_deselect_target(device);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("Can't deselect target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("Can't deselect target: %s", nfc_strerror(device)));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
// Passive mode / 212Kbps
|
||||
printf("=========== INITIATOR %s (Passive mode / 212Kbps, second pass) =========\n", nfc_device_get_name(device));
|
||||
res = nfc_initiator_select_dep_target(device, NDM_PASSIVE, NBR_212, NULL, &nt, 1000);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't select any DEP target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't select any DEP target: %s", nfc_strerror(device)));
|
||||
cut_assert_equal_int(NMT_DEP, nt.nm.nmt, cut_message("Invalid target modulation"));
|
||||
cut_assert_equal_int(NBR_212, nt.nm.nbr, cut_message("Invalid target baud rate"));
|
||||
cut_assert_equal_memory("\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA", 10, nt.nti.ndi.abtNFCID3, 10, cut_message("Invalid target NFCID3"));
|
||||
@ -214,19 +214,19 @@ initiator_thread(void *arg)
|
||||
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
res = nfc_initiator_transceive_bytes(device, abtTx, sizeof(abtTx), abtRx, sizeof(abtRx), 5000);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("Can't transceive bytes to target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("Can't transceive bytes to target: %s", nfc_strerror(device)));
|
||||
|
||||
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
res = nfc_initiator_deselect_target(device);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("Can't deselect target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("Can't deselect target: %s", nfc_strerror(device)));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
// Passive mode / 424Kbps
|
||||
printf("=========== INITIATOR %s (Passive mode / 424Kbps) =========\n", nfc_device_get_name(device));
|
||||
res = nfc_initiator_select_dep_target(device, NDM_PASSIVE, NBR_424, NULL, &nt, 1000);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't select any DEP target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't select any DEP target: %s", nfc_strerror(device)));
|
||||
cut_assert_equal_int(NMT_DEP, nt.nm.nmt, cut_message("Invalid target modulation"));
|
||||
cut_assert_equal_int(NBR_424, nt.nm.nbr, cut_message("Invalid target baud rate"));
|
||||
cut_assert_equal_memory("\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA", 10, nt.nti.ndi.abtNFCID3, 10, cut_message("Invalid target NFCID3"));
|
||||
@ -235,13 +235,13 @@ initiator_thread(void *arg)
|
||||
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
res = nfc_initiator_transceive_bytes(device, abtTx, sizeof(abtTx), abtRx, sizeof(abtRx), 5000);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("Can't transceive bytes to target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("Can't transceive bytes to target: %s", nfc_strerror(device)));
|
||||
|
||||
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
res = nfc_initiator_deselect_target(device);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("Can't deselect target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("Can't deselect target: %s", nfc_strerror(device)));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
return (void *) thread_res;
|
||||
|
||||
@ -66,7 +66,7 @@ target_thread(void *arg)
|
||||
|
||||
// 1) nfc_target_init should take target in idle mode
|
||||
int res = nfc_target_init(device, &nt, abtRx, sizeof(abtRx), 500);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("Can't initialize NFC device as target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("Can't initialize NFC device as target: %s", nfc_strerror(device)));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
// 2) act as target
|
||||
@ -92,11 +92,11 @@ target_thread(void *arg)
|
||||
};
|
||||
sleep(6);
|
||||
res = nfc_target_init(device, &nt1, abtRx, sizeof(abtRx), 0);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't initialize NFC device as target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't initialize NFC device as target: %s", nfc_strerror(device)));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
res = nfc_target_receive_bytes(device, abtRx, sizeof(abtRx), 500);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
|
||||
|
||||
const uint8_t abtAttRx[] = "Hello DEP target!";
|
||||
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
|
||||
@ -104,7 +104,7 @@ target_thread(void *arg)
|
||||
|
||||
const uint8_t abtTx[] = "Hello DEP initiator!";
|
||||
res = nfc_target_send_bytes(device, abtTx, sizeof(abtTx), 500);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't send bytes to initiator: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't send bytes to initiator: %s", nfc_strerror(device)));
|
||||
if (res <= 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
// 3) idle mode
|
||||
@ -144,7 +144,7 @@ initiator_thread(void *arg)
|
||||
// Passive mode / 106Kbps
|
||||
printf("=========== INITIATOR %s (Passive mode / 106Kbps) =========\n", nfc_device_get_name(device));
|
||||
res = nfc_initiator_poll_dep_target(device, NDM_PASSIVE, NBR_106, NULL, &nt1, 5000);
|
||||
cut_assert_operator_int(res, > , 0, cut_message("Can't select any DEP target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >, 0, cut_message("Can't select any DEP target: %s", nfc_strerror(device)));
|
||||
cut_assert_equal_int(NMT_DEP, nt1.nm.nmt, cut_message("Invalid target modulation"));
|
||||
cut_assert_equal_int(NBR_106, nt1.nm.nbr, cut_message("Invalid target baud rate"));
|
||||
cut_assert_equal_memory("\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA", 10, nt1.nti.ndi.abtNFCID3, 10, cut_message("Invalid target NFCID3"));
|
||||
@ -155,14 +155,14 @@ initiator_thread(void *arg)
|
||||
const uint8_t abtTx[] = "Hello DEP target!";
|
||||
uint8_t abtRx[1024];
|
||||
res = nfc_initiator_transceive_bytes(device, abtTx, sizeof(abtTx), abtRx, sizeof(abtRx), 500);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("Can't transceive bytes to target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("Can't transceive bytes to target: %s", nfc_strerror(device)));
|
||||
|
||||
const uint8_t abtAttRx[] = "Hello DEP initiator!";
|
||||
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
res = nfc_initiator_deselect_target(device);
|
||||
cut_assert_operator_int(res, >= , 0, cut_message("Can't deselect target: %s", nfc_strerror(device)));
|
||||
cut_assert_operator_int(res, >=, 0, cut_message("Can't deselect target: %s", nfc_strerror(device)));
|
||||
if (res < 0) { thread_res = -1; return (void *) thread_res; }
|
||||
|
||||
// 3) As other device should be in idle mode, nfc_initiator_poll_dep_target should return 0
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
SET(UTILS-SOURCES
|
||||
nfc-barcode
|
||||
nfc-emulate-forum-tag4
|
||||
nfc-jewel
|
||||
nfc-list
|
||||
@ -22,7 +23,8 @@ FOREACH(source ${UTILS-SOURCES})
|
||||
SET(RC_COMMENT "${PACKAGE_NAME} utility")
|
||||
SET(RC_INTERNAL_NAME ${source})
|
||||
SET(RC_ORIGINAL_NAME ${source}.exe)
|
||||
SET(RC_FILE_TYPE VFT_APP)
|
||||
# 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)
|
||||
ENDIF(WIN32)
|
||||
@ -40,6 +42,9 @@ FOREACH(source ${UTILS-SOURCES})
|
||||
LIST(APPEND TARGETS ../contrib/win32/stdlib)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32)
|
||||
ENDIF(${source} MATCHES "nfc-scan-device")
|
||||
IF(${source} MATCHES "nfc-read-forum-tag3")
|
||||
LIST(APPEND TARGETS ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/win32/getopt.c)
|
||||
ENDIF()
|
||||
ENDIF(WIN32)
|
||||
|
||||
ADD_EXECUTABLE(${source} ${TARGETS})
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user