Merge libnfc-1.5-new-api branch to trunk (r1168:1303).
This commit is contained in:
commit
26245add73
82 changed files with 4481 additions and 3212 deletions
|
@ -10,9 +10,7 @@ pkgconfig_DATA = libnfc.pc
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
CMakeLists.txt \
|
CMakeLists.txt \
|
||||||
Doxyfile \
|
Doxyfile \
|
||||||
README-Windows.txt \
|
README-Windows.txt
|
||||||
pn53x.conf \
|
|
||||||
pn53x.rules
|
|
||||||
|
|
||||||
CLEANFILES = Doxygen.log coverage.info libnfc.pc
|
CLEANFILES = Doxygen.log coverage.info libnfc.pc
|
||||||
|
|
||||||
|
|
13
configure.ac
13
configure.ac
|
@ -70,17 +70,6 @@ AC_TYPE_SIGNAL
|
||||||
LIBNFC_CFLAGS='-I$(top_srcdir)/libnfc -I$(top_builddir)/include -I$(top_srcdir)/include'
|
LIBNFC_CFLAGS='-I$(top_srcdir)/libnfc -I$(top_builddir)/include -I$(top_srcdir)/include'
|
||||||
AC_SUBST(LIBNFC_CFLAGS)
|
AC_SUBST(LIBNFC_CFLAGS)
|
||||||
|
|
||||||
# Checks for log4c
|
|
||||||
AC_PATH_PROG([LOG4C_CONFIG], [log4c-config])
|
|
||||||
if test x"$LOG4C_CONFIG" != x""; then
|
|
||||||
log4c_CFLAGS=`$LOG4C_CONFIG --cflags`
|
|
||||||
log4c_LIBS=`$LOG4C_CONFIG --libs`
|
|
||||||
AC_SUBST([log4c_CFLAGS])
|
|
||||||
AC_SUBST([log4c_LIBS])
|
|
||||||
AC_DEFINE([HAS_LOG4C], [1], [Define to 1 if log4c is available.])
|
|
||||||
fi
|
|
||||||
AM_CONDITIONAL(HAS_LOG4C, [test x"$LOG4C_CONFIG" != x""])
|
|
||||||
|
|
||||||
# Debug support (default:no)
|
# Debug support (default:no)
|
||||||
AC_ARG_ENABLE([debug],AS_HELP_STRING([--enable-debug],[Enable debug output]),[enable_debug=$enableval],[enable_debug="no"])
|
AC_ARG_ENABLE([debug],AS_HELP_STRING([--enable-debug],[Enable debug output]),[enable_debug=$enableval],[enable_debug="no"])
|
||||||
|
|
||||||
|
@ -155,6 +144,8 @@ AC_CONFIG_FILES([
|
||||||
cmake/Makefile
|
cmake/Makefile
|
||||||
cmake/modules/Makefile
|
cmake/modules/Makefile
|
||||||
contrib/Makefile
|
contrib/Makefile
|
||||||
|
contrib/devd/Makefile
|
||||||
|
contrib/udev/Makefile
|
||||||
contrib/win32/Makefile
|
contrib/win32/Makefile
|
||||||
contrib/win32/sys/Makefile
|
contrib/win32/sys/Makefile
|
||||||
examples/Makefile
|
examples/Makefile
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
SUBDIRS = win32
|
SUBDIRS = \
|
||||||
|
devd \
|
||||||
|
udev \
|
||||||
|
win32
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
windows.h
|
windows.h
|
||||||
|
|
2
contrib/devd/Makefile.am
Normal file
2
contrib/devd/Makefile.am
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
EXTRA_DIST = \
|
||||||
|
pn53x.conf
|
2
contrib/udev/Makefile.am
Normal file
2
contrib/udev/Makefile.am
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
EXTRA_DIST = \
|
||||||
|
42-pn53x.rules
|
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -1,3 +1,9 @@
|
||||||
|
libnfc (1.5.1pre2.1-0) unstable; urgency=low
|
||||||
|
|
||||||
|
* Udev rules file renamed accordingly to udev's README file
|
||||||
|
|
||||||
|
-- Romuald Conty <rconty@il4p.fr> Fri, 9 Dec 2011 15:42:42 +0100
|
||||||
|
|
||||||
libnfc (1.5.1-0) unstable; urgency=low
|
libnfc (1.5.1-0) unstable; urgency=low
|
||||||
|
|
||||||
* Move nfc-emulate-nfcforum-tag2, nfc-emulate-nfcforum-tag4 and
|
* Move nfc-emulate-nfcforum-tag2, nfc-emulate-nfcforum-tag4 and
|
||||||
|
|
2
debian/libnfc2.install
vendored
2
debian/libnfc2.install
vendored
|
@ -1,2 +1,2 @@
|
||||||
debian/tmp/usr/lib/libnfc.so.*
|
debian/tmp/usr/lib/libnfc.so.*
|
||||||
pn53x.rules lib/udev/rules.d
|
contrib/udev/42-pn53x.rules lib/udev/rules.d/
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
SET(EXAMPLES-SOURCES nfc-anticol nfc-dep-initiator nfc-dep-target nfc-emulate-tag nfc-emulate-uid nfc-poll nfc-relay)
|
SET(EXAMPLES-SOURCES nfc-anticol nfc-dep-initiator nfc-dep-target nfc-emulate-forum-tag2 nfc-emulate-tag nfc-emulate-uid nfc-poll nfc-relay)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libnfc)
|
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libnfc)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ bin_PROGRAMS = \
|
||||||
nfc-anticol \
|
nfc-anticol \
|
||||||
nfc-dep-initiator \
|
nfc-dep-initiator \
|
||||||
nfc-dep-target \
|
nfc-dep-target \
|
||||||
|
nfc-emulate-forum-tag2 \
|
||||||
nfc-emulate-tag \
|
nfc-emulate-tag \
|
||||||
nfc-emulate-uid \
|
nfc-emulate-uid \
|
||||||
nfc-poll \
|
nfc-poll \
|
||||||
|
@ -16,6 +17,9 @@ bin_PROGRAMS += \
|
||||||
pn53x-tamashell
|
pn53x-tamashell
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
check_PROGRAMS = \
|
||||||
|
quick_start_example1
|
||||||
|
|
||||||
# set the include path found by configure
|
# set the include path found by configure
|
||||||
INCLUDES = $(all_includes) $(LIBNFC_CFLAGS)
|
INCLUDES = $(all_includes) $(LIBNFC_CFLAGS)
|
||||||
|
|
||||||
|
@ -33,6 +37,10 @@ nfc_relay_SOURCES = nfc-relay.c
|
||||||
nfc_relay_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
nfc_relay_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
||||||
$(top_builddir)/utils/libnfcutils.la
|
$(top_builddir)/utils/libnfcutils.la
|
||||||
|
|
||||||
|
nfc_emulate_forum_tag2_SOURCES = nfc-emulate-forum-tag2.c
|
||||||
|
nfc_emulate_forum_tag2_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
||||||
|
$(top_builddir)/utils/libnfcutils.la
|
||||||
|
|
||||||
nfc_emulate_tag_SOURCES = nfc-emulate-tag.c
|
nfc_emulate_tag_SOURCES = nfc-emulate-tag.c
|
||||||
nfc_emulate_tag_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
nfc_emulate_tag_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
||||||
$(top_builddir)/utils/libnfcutils.la
|
$(top_builddir)/utils/libnfcutils.la
|
||||||
|
@ -62,6 +70,11 @@ pn53x_tamashell_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
||||||
$(top_builddir)/utils/libnfcutils.la
|
$(top_builddir)/utils/libnfcutils.la
|
||||||
pn53x_tamashell_LDFLAGS = @READLINE_LIBS@
|
pn53x_tamashell_LDFLAGS = @READLINE_LIBS@
|
||||||
|
|
||||||
|
quick_start_example1_SOURCES = doc/quick_start_example1.c
|
||||||
|
quick_start_example1_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
||||||
|
$(top_builddir)/utils/libnfcutils.la
|
||||||
|
|
||||||
|
|
||||||
dist_man_MANS = \
|
dist_man_MANS = \
|
||||||
nfc-anticol.1 \
|
nfc-anticol.1 \
|
||||||
nfc-dep-initiator.1 \
|
nfc-dep-initiator.1 \
|
||||||
|
@ -74,9 +87,4 @@ dist_man_MANS = \
|
||||||
pn53x-sam.1 \
|
pn53x-sam.1 \
|
||||||
pn53x-tamashell.1
|
pn53x-tamashell.1
|
||||||
|
|
||||||
if HAS_LOG4C
|
|
||||||
AM_CFLAGS += @log4c_CFLAGS@
|
|
||||||
LIBADD = @log4c_LIBS@
|
|
||||||
endif
|
|
||||||
|
|
||||||
EXTRA_DIST = CMakeLists.txt
|
EXTRA_DIST = CMakeLists.txt
|
||||||
|
|
|
@ -5,45 +5,42 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <nfc/nfc.h>
|
#include <nfc/nfc.h>
|
||||||
|
|
||||||
void
|
#include "utils/nfc-utils.h"
|
||||||
print_hex (const byte_t * pbtData, const size_t szBytes)
|
#include "libnfc/chips/pn53x.h"
|
||||||
{
|
|
||||||
size_t szPos;
|
|
||||||
|
|
||||||
for (szPos = 0; szPos < szBytes; szPos++) {
|
|
||||||
printf ("%02x ", pbtData[szPos]);
|
|
||||||
}
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, const char *argv[])
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
nfc_device_t *pnd;
|
nfc_device *pnd;
|
||||||
nfc_target_t nt;
|
nfc_target nt;
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
// Display libnfc version
|
// Display libnfc version
|
||||||
const char *acLibnfcVersion = nfc_version ();
|
const char *acLibnfcVersion = nfc_version ();
|
||||||
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
|
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
|
||||||
|
|
||||||
// Connect using the first available NFC device
|
// Open, using the first available NFC device
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_open (NULL, NULL);
|
||||||
|
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
fprintf (stderr, "Unable to connect to NFC device.");
|
ERR ("%s", "Unable to open NFC device.");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
// Set connected NFC device to initiator mode
|
// Set opened NFC device to initiator mode
|
||||||
nfc_initiator_init (pnd);
|
if (nfc_initiator_init (pnd) < 0) {
|
||||||
|
nfc_perror (pnd, "nfc_initiator_init");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
printf ("NFC reader: %s opened\n", nfc_device_get_name (pnd));
|
||||||
|
|
||||||
// Poll for a ISO14443A (MIFARE) tag
|
// Poll for a ISO14443A (MIFARE) tag
|
||||||
const nfc_modulation_t nmMifare = {
|
const nfc_modulation nmMifare = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
.nbr = NBR_106,
|
.nbr = NBR_106,
|
||||||
};
|
};
|
||||||
if (nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
|
if (nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt) > 0) {
|
||||||
printf ("The following (NFC) ISO14443A tag was found:\n");
|
printf ("The following (NFC) ISO14443A tag was found:\n");
|
||||||
printf (" ATQA (SENS_RES): ");
|
printf (" ATQA (SENS_RES): ");
|
||||||
print_hex (nt.nti.nai.abtAtqa, 2);
|
print_hex (nt.nti.nai.abtAtqa, 2);
|
||||||
|
@ -56,7 +53,8 @@ main (int argc, const char *argv[])
|
||||||
print_hex (nt.nti.nai.abtAts, nt.nti.nai.szAtsLen);
|
print_hex (nt.nti.nai.abtAts, nt.nti.nai.szAtsLen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Disconnect from NFC device
|
// Close NFC device
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,31 +51,31 @@
|
||||||
|
|
||||||
#define MAX_FRAME_LEN 264
|
#define MAX_FRAME_LEN 264
|
||||||
|
|
||||||
static byte_t abtRx[MAX_FRAME_LEN];
|
static uint8_t abtRx[MAX_FRAME_LEN];
|
||||||
static size_t szRxBits;
|
static int szRxBits;
|
||||||
static size_t szRx = sizeof(abtRx);
|
static size_t szRx = sizeof(abtRx);
|
||||||
static byte_t abtRawUid[12];
|
static uint8_t abtRawUid[12];
|
||||||
static byte_t abtAtqa[2];
|
static uint8_t abtAtqa[2];
|
||||||
static byte_t abtSak;
|
static uint8_t abtSak;
|
||||||
static byte_t abtAts[MAX_FRAME_LEN];
|
static uint8_t abtAts[MAX_FRAME_LEN];
|
||||||
static byte_t szAts = 0;
|
static uint8_t szAts = 0;
|
||||||
static size_t szCL = 1;//Always start with Cascade Level 1 (CL1)
|
static size_t szCL = 1;//Always start with Cascade Level 1 (CL1)
|
||||||
static nfc_device_t *pnd;
|
static nfc_device *pnd;
|
||||||
|
|
||||||
bool quiet_output = false;
|
bool quiet_output = false;
|
||||||
bool force_rats = false;
|
bool force_rats = false;
|
||||||
bool iso_ats_supported = false;
|
bool iso_ats_supported = false;
|
||||||
|
|
||||||
// ISO14443A Anti-Collision Commands
|
// ISO14443A Anti-Collision Commands
|
||||||
byte_t abtReqa[1] = { 0x26 };
|
uint8_t abtReqa[1] = { 0x26 };
|
||||||
byte_t abtSelectAll[2] = { 0x93, 0x20 };
|
uint8_t abtSelectAll[2] = { 0x93, 0x20 };
|
||||||
byte_t abtSelectTag[9] = { 0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t abtSelectTag[9] = { 0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
byte_t abtRats[4] = { 0xe0, 0x50, 0x00, 0x00 };
|
uint8_t abtRats[4] = { 0xe0, 0x50, 0x00, 0x00 };
|
||||||
byte_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
|
uint8_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
|
||||||
#define CASCADE_BIT 0x04
|
#define CASCADE_BIT 0x04
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
|
transmit_bits (const uint8_t *pbtTx, const size_t szTxBits)
|
||||||
{
|
{
|
||||||
// Show transmitted command
|
// Show transmitted command
|
||||||
if (!quiet_output) {
|
if (!quiet_output) {
|
||||||
|
@ -83,7 +83,7 @@ transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
|
||||||
print_hex_bits (pbtTx, szTxBits);
|
print_hex_bits (pbtTx, szTxBits);
|
||||||
}
|
}
|
||||||
// Transmit the bit frame command, we don't use the arbitrary parity feature
|
// Transmit the bit frame command, we don't use the arbitrary parity feature
|
||||||
if (!nfc_initiator_transceive_bits (pnd, pbtTx, szTxBits, NULL, abtRx, &szRxBits, NULL))
|
if ((szRxBits = nfc_initiator_transceive_bits (pnd, pbtTx, szTxBits, NULL, abtRx, NULL)) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Show received answer
|
// Show received answer
|
||||||
|
@ -97,7 +97,7 @@ transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
transmit_bytes (const byte_t * pbtTx, const size_t szTx)
|
transmit_bytes (const uint8_t *pbtTx, const size_t szTx)
|
||||||
{
|
{
|
||||||
// Show transmitted command
|
// Show transmitted command
|
||||||
if (!quiet_output) {
|
if (!quiet_output) {
|
||||||
|
@ -105,7 +105,7 @@ transmit_bytes (const byte_t * pbtTx, const size_t szTx)
|
||||||
print_hex (pbtTx, szTx);
|
print_hex (pbtTx, szTx);
|
||||||
}
|
}
|
||||||
// Transmit the command bytes
|
// Transmit the command bytes
|
||||||
if (!nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, &szRx, NULL))
|
if (nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, &szRx, 0) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Show received answer
|
// Show received answer
|
||||||
|
@ -148,39 +148,45 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
// Try to open the NFC reader
|
// Try to open the NFC reader
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_open (NULL, NULL);
|
||||||
|
|
||||||
if (!pnd) {
|
if (!pnd) {
|
||||||
printf ("Error connecting NFC reader\n");
|
printf ("Error opening NFC reader\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialise NFC device as "initiator"
|
// Initialise NFC device as "initiator"
|
||||||
nfc_initiator_init (pnd);
|
if (nfc_initiator_init (pnd) < 0) {
|
||||||
|
nfc_perror (pnd, "nfc_initiator_init");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
// Configure the CRC
|
// Configure the CRC
|
||||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, false)) {
|
if (nfc_device_set_property_bool (pnd, NP_HANDLE_CRC, false) < 0) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
// Use raw send/receive methods
|
// Use raw send/receive methods
|
||||||
if (!nfc_configure (pnd, NDO_EASY_FRAMING, false)) {
|
if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, false) < 0) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
// Disable 14443-4 autoswitching
|
// Disable 14443-4 autoswitching
|
||||||
if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, false)) {
|
if (nfc_device_set_property_bool (pnd, NP_AUTO_ISO14443_4, false) < 0) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Connected to NFC reader: %s\n\n", pnd->acName);
|
printf ("NFC reader: %s opened\n\n", nfc_device_get_name (pnd));
|
||||||
|
|
||||||
// Send the 7 bits request command specified in ISO 14443A (0x26)
|
// Send the 7 bits request command specified in ISO 14443A (0x26)
|
||||||
if (!transmit_bits (abtReqa, 7)) {
|
if (!transmit_bits (abtReqa, 7)) {
|
||||||
printf ("Error: No tag available\n");
|
printf ("Error: No tag available\n");
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
memcpy (abtAtqa, abtRx, 2);
|
memcpy (abtAtqa, abtRx, 2);
|
||||||
|
@ -309,6 +315,7 @@ main (int argc, char *argv[])
|
||||||
print_hex (abtAts, szAts);
|
print_hex (abtAts, szAts);
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
#define MAX_FRAME_LEN 264
|
#define MAX_FRAME_LEN 264
|
||||||
|
|
||||||
static nfc_device_t *pnd;
|
static nfc_device *pnd;
|
||||||
|
|
||||||
void stop_dep_communication (int sig)
|
void stop_dep_communication (int sig)
|
||||||
{
|
{
|
||||||
|
@ -62,38 +62,40 @@ void stop_dep_communication (int sig)
|
||||||
int
|
int
|
||||||
main (int argc, const char *argv[])
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
nfc_target_t nt;
|
nfc_target nt;
|
||||||
byte_t abtRx[MAX_FRAME_LEN];
|
uint8_t abtRx[MAX_FRAME_LEN];
|
||||||
size_t szRx = sizeof(abtRx);
|
size_t szRx = sizeof(abtRx);
|
||||||
byte_t abtTx[] = "Hello World!";
|
uint8_t abtTx[] = "Hello World!";
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
printf ("Usage: %s\n", argv[0]);
|
printf ("Usage: %s\n", argv[0]);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_open (NULL, NULL);
|
||||||
if (!pnd) {
|
if (!pnd) {
|
||||||
printf("Unable to connect to NFC device.\n");
|
printf("Unable to open NFC device.\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf ("Connected to NFC device: %s\n", pnd->acName);
|
printf ("NFC device: %s\n opened", nfc_device_get_name (pnd));
|
||||||
|
|
||||||
signal (SIGINT, stop_dep_communication);
|
signal (SIGINT, stop_dep_communication);
|
||||||
|
|
||||||
if (!nfc_initiator_init (pnd)) {
|
if (nfc_initiator_init (pnd) < 0) {
|
||||||
nfc_perror(pnd, "nfc_initiator_init");
|
nfc_perror(pnd, "nfc_initiator_init");
|
||||||
return EXIT_FAILURE;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!nfc_initiator_select_dep_target (pnd, NDM_PASSIVE, NBR_212, NULL, &nt)) {
|
if(nfc_initiator_select_dep_target (pnd, NDM_PASSIVE, NBR_212, NULL, &nt, 1000) < 0) {
|
||||||
nfc_perror(pnd, "nfc_initiator_select_dep_target");
|
nfc_perror(pnd, "nfc_initiator_select_dep_target");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
print_nfc_target (nt, false);
|
print_nfc_target (nt, false);
|
||||||
|
|
||||||
printf ("Sending: %s\n", abtTx);
|
printf ("Sending: %s\n", abtTx);
|
||||||
if (!nfc_initiator_transceive_bytes (pnd, abtTx, sizeof(abtTx), abtRx, &szRx, NULL)) {
|
if (nfc_initiator_transceive_bytes (pnd, abtTx, sizeof(abtTx), abtRx, &szRx, 0) < 0) {
|
||||||
nfc_perror(pnd, "nfc_initiator_transceive_bytes");
|
nfc_perror(pnd, "nfc_initiator_transceive_bytes");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -101,9 +103,13 @@ main (int argc, const char *argv[])
|
||||||
abtRx[szRx] = 0;
|
abtRx[szRx] = 0;
|
||||||
printf ("Received: %s\n", abtRx);
|
printf ("Received: %s\n", abtRx);
|
||||||
|
|
||||||
nfc_initiator_deselect_target (pnd);
|
if (nfc_initiator_deselect_target (pnd) < 0) {
|
||||||
|
nfc_perror(pnd, "nfc_initiator_deselect_target");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
#define MAX_FRAME_LEN 264
|
#define MAX_FRAME_LEN 264
|
||||||
|
|
||||||
static nfc_device_t *pnd;
|
static nfc_device *pnd;
|
||||||
|
|
||||||
void stop_dep_communication (int sig)
|
void stop_dep_communication (int sig)
|
||||||
{
|
{
|
||||||
|
@ -61,23 +61,23 @@ void stop_dep_communication (int sig)
|
||||||
int
|
int
|
||||||
main (int argc, const char *argv[])
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
byte_t abtRx[MAX_FRAME_LEN];
|
uint8_t abtRx[MAX_FRAME_LEN];
|
||||||
size_t szRx = sizeof(abtRx);
|
int szRx;
|
||||||
size_t szDeviceFound;
|
uint8_t abtTx[] = "Hello Mars!";
|
||||||
byte_t abtTx[] = "Hello Mars!";
|
|
||||||
#define MAX_DEVICE_COUNT 2
|
#define MAX_DEVICE_COUNT 2
|
||||||
nfc_device_desc_t pnddDevices[MAX_DEVICE_COUNT];
|
nfc_connstring connstrings[MAX_DEVICE_COUNT];
|
||||||
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szDeviceFound);
|
size_t szDeviceFound = nfc_list_devices (NULL, connstrings, MAX_DEVICE_COUNT);
|
||||||
// Little hack to allow using nfc-dep-initiator & nfc-dep-target from
|
// Little hack to allow using nfc-dep-initiator & nfc-dep-target from
|
||||||
// the same machine: if there is more than one readers connected
|
// the same machine: if there is more than one readers opened
|
||||||
// nfc-dep-target will connect to the second reader
|
// nfc-dep-target will open the second reader
|
||||||
// (we hope they're always detected in the same order)
|
// (we hope they're always detected in the same order)
|
||||||
|
nfc_init (NULL);
|
||||||
if (szDeviceFound == 1) {
|
if (szDeviceFound == 1) {
|
||||||
pnd = nfc_connect (&(pnddDevices[0]));
|
pnd = nfc_open (NULL, connstrings[0]);
|
||||||
} else if (szDeviceFound > 1) {
|
} else if (szDeviceFound > 1) {
|
||||||
pnd = nfc_connect (&(pnddDevices[1]));
|
pnd = nfc_open (NULL, connstrings[1]);
|
||||||
} else {
|
} else {
|
||||||
printf("No device found.");
|
printf("No device found.\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ main (int argc, const char *argv[])
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_target_t nt = {
|
nfc_target nt = {
|
||||||
.nm = {
|
.nm = {
|
||||||
.nmt = NMT_DEP,
|
.nmt = NMT_DEP,
|
||||||
.nbr = NBR_UNDEFINED
|
.nbr = NBR_UNDEFINED
|
||||||
|
@ -108,10 +108,10 @@ main (int argc, const char *argv[])
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!pnd) {
|
if (!pnd) {
|
||||||
printf("Unable to connect to NFC device.\n");
|
printf("Unable to open NFC device.\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf ("Connected to NFC device: %s\n", pnd->acName);
|
printf ("NFC device: %s opened\n", nfc_device_get_name (pnd));
|
||||||
|
|
||||||
signal (SIGINT, stop_dep_communication);
|
signal (SIGINT, stop_dep_communication);
|
||||||
|
|
||||||
|
@ -119,27 +119,28 @@ main (int argc, const char *argv[])
|
||||||
print_nfc_target (nt, false);
|
print_nfc_target (nt, false);
|
||||||
|
|
||||||
printf ("Waiting for initiator request...\n");
|
printf ("Waiting for initiator request...\n");
|
||||||
if(!nfc_target_init (pnd, &nt, abtRx, &szRx)) {
|
if ((szRx = nfc_target_init (pnd, &nt, abtRx, sizeof(abtRx), 0)) < 0) {
|
||||||
nfc_perror(pnd, "nfc_target_init");
|
nfc_perror(pnd, "nfc_target_init");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Initiator request received. Waiting for data...\n");
|
printf("Initiator request received. Waiting for data...\n");
|
||||||
if (!nfc_target_receive_bytes (pnd, abtRx, &szRx, NULL)) {
|
if ((szRx = nfc_target_receive_bytes (pnd, abtRx, sizeof (abtRx), 0)) < 0) {
|
||||||
nfc_perror(pnd, "nfc_target_receive_bytes");
|
nfc_perror(pnd, "nfc_target_receive_bytes");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
abtRx[szRx] = '\0';
|
abtRx[(size_t) szRx] = '\0';
|
||||||
printf ("Received: %s\n", abtRx);
|
printf ("Received: %s\n", abtRx);
|
||||||
|
|
||||||
printf ("Sending: %s\n", abtTx);
|
printf ("Sending: %s\n", abtTx);
|
||||||
if (!nfc_target_send_bytes (pnd, abtTx, sizeof(abtTx), NULL)) {
|
if (nfc_target_send_bytes (pnd, abtTx, sizeof(abtTx), 0) < 0) {
|
||||||
nfc_perror(pnd, "nfc_target_send_bytes");
|
nfc_perror(pnd, "nfc_target_send_bytes");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
printf("Data sent.\n");
|
printf("Data sent.\n");
|
||||||
|
|
||||||
error:
|
error:
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,9 +69,9 @@
|
||||||
#include <nfc/nfc.h>
|
#include <nfc/nfc.h>
|
||||||
#include <nfc/nfc-emulation.h>
|
#include <nfc/nfc-emulation.h>
|
||||||
|
|
||||||
#include "nfc-utils.h"
|
#include "utils/nfc-utils.h"
|
||||||
|
|
||||||
static nfc_device_t *pnd;
|
static nfc_device *pnd;
|
||||||
|
|
||||||
void
|
void
|
||||||
stop_emulation (int sig)
|
stop_emulation (int sig)
|
||||||
|
@ -112,7 +112,7 @@ static uint8_t __nfcforum_tag2_memory_area[] = {
|
||||||
|
|
||||||
#define HALT 0x50
|
#define HALT 0x50
|
||||||
int
|
int
|
||||||
nfcforum_tag2_io (struct nfc_emulator *emulator, const byte_t *data_in, const size_t data_in_len, byte_t *data_out, const size_t data_out_len)
|
nfcforum_tag2_io (struct nfc_emulator *emulator, const uint8_t *data_in, const size_t data_in_len, uint8_t *data_out, const size_t data_out_len)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ main(int argc, char *argv[])
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
||||||
nfc_target_t nt = {
|
nfc_target nt = {
|
||||||
.nm = {
|
.nm = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
.nbr = NBR_UNDEFINED, // Will be updated by nfc_target_init()
|
.nbr = NBR_UNDEFINED, // Will be updated by nfc_target_init()
|
||||||
|
@ -172,37 +172,40 @@ main(int argc, char *argv[])
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nfc_emulation_state_machine state_machine = {
|
struct nfc_emulation_state_machine state_machine = {
|
||||||
.io = nfcforum_tag2_io
|
.io = nfcforum_tag2_io
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nfc_emulator emulator = {
|
struct nfc_emulator emulator = {
|
||||||
.target= &nt,
|
.target = &nt,
|
||||||
.state_machine = &state_machine,
|
.state_machine = &state_machine,
|
||||||
.user_data = __nfcforum_tag2_memory_area,
|
.user_data = __nfcforum_tag2_memory_area,
|
||||||
};
|
};
|
||||||
|
|
||||||
signal (SIGINT, stop_emulation);
|
signal (SIGINT, stop_emulation);
|
||||||
pnd = nfc_connect (NULL);
|
nfc_init (NULL);
|
||||||
|
pnd = nfc_open (NULL, NULL);
|
||||||
|
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
ERR("Unable to connect to NFC device");
|
ERR("Unable to open NFC device");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Connected to NFC device: %s\n", pnd->acName);
|
printf ("NFC device: %s opened\n", nfc_device_get_name (pnd));
|
||||||
printf ("Emulating NDEF tag now, please touch it with a second NFC device\n");
|
printf ("Emulating NDEF tag now, please touch it with a second NFC device\n");
|
||||||
|
|
||||||
if (nfc_emulate_target (pnd, &emulator) < 0) {
|
if (nfc_emulate_target (pnd, &emulator) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_disconnect(pnd);
|
nfc_close(pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
|
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (pnd) {
|
if (pnd) {
|
||||||
nfc_perror (pnd, argv[0]);
|
nfc_perror (pnd, argv[0]);
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -54,9 +54,9 @@
|
||||||
#define MAX_FRAME_LEN (264)
|
#define MAX_FRAME_LEN (264)
|
||||||
#define SAK_ISO14443_4_COMPLIANT 0x20
|
#define SAK_ISO14443_4_COMPLIANT 0x20
|
||||||
|
|
||||||
static byte_t abtRx[MAX_FRAME_LEN];
|
static uint8_t abtRx[MAX_FRAME_LEN];
|
||||||
static size_t szRx = sizeof(abtRx);
|
static int szRx;
|
||||||
static nfc_device_t *pnd;
|
static nfc_device *pnd;
|
||||||
static bool quiet_output = false;
|
static bool quiet_output = false;
|
||||||
static bool init_mfc_auth = false;
|
static bool init_mfc_auth = false;
|
||||||
|
|
||||||
|
@ -65,13 +65,14 @@ intr_hdlr (void)
|
||||||
{
|
{
|
||||||
printf ("\nQuitting...\n");
|
printf ("\nQuitting...\n");
|
||||||
if (pnd != NULL) {
|
if (pnd != NULL) {
|
||||||
nfc_disconnect(pnd);
|
nfc_close(pnd);
|
||||||
}
|
}
|
||||||
|
nfc_exit (NULL);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
target_io( nfc_target_t * pnt, const byte_t * pbtInput, const size_t szInput, byte_t * pbtOutput, size_t *pszOutput )
|
target_io( nfc_target *pnt, const uint8_t *pbtInput, const size_t szInput, uint8_t *pbtOutput, size_t *pszOutput )
|
||||||
{
|
{
|
||||||
bool loop = true;
|
bool loop = true;
|
||||||
*pszOutput = 0;
|
*pszOutput = 0;
|
||||||
|
@ -134,31 +135,31 @@ target_io( nfc_target_t * pnt, const byte_t * pbtInput, const size_t szInput, by
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nfc_target_emulate_tag(nfc_device_t* pnd, nfc_target_t * pnt)
|
nfc_target_emulate_tag(nfc_device *pnd, nfc_target *pnt)
|
||||||
{
|
{
|
||||||
size_t szTx;
|
size_t szTx;
|
||||||
byte_t abtTx[MAX_FRAME_LEN];
|
uint8_t abtTx[MAX_FRAME_LEN];
|
||||||
bool loop = true;
|
bool loop = true;
|
||||||
|
|
||||||
if (!nfc_target_init (pnd, pnt, abtRx, &szRx)) {
|
if ((szRx = nfc_target_init (pnd, pnt, abtRx, sizeof(abtRx), 0)) < 0) {
|
||||||
nfc_perror (pnd, "nfc_target_init");
|
nfc_perror (pnd, "nfc_target_init");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( loop ) {
|
while ( loop ) {
|
||||||
loop = target_io( pnt, abtRx, szRx, abtTx, &szTx );
|
loop = target_io( pnt, abtRx, (size_t) szRx, abtTx, &szTx );
|
||||||
if (szTx) {
|
if (szTx) {
|
||||||
if (!nfc_target_send_bytes(pnd, abtTx, szTx, NULL)) {
|
if (nfc_target_send_bytes(pnd, abtTx, szTx, 0) < 0) {
|
||||||
nfc_perror (pnd, "nfc_target_send_bytes");
|
nfc_perror (pnd, "nfc_target_send_bytes");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( loop ) {
|
if ( loop ) {
|
||||||
if ( init_mfc_auth ) {
|
if ( init_mfc_auth ) {
|
||||||
nfc_configure (pnd, NDO_HANDLE_CRC, false);
|
nfc_device_set_property_bool (pnd, NP_HANDLE_CRC, false);
|
||||||
init_mfc_auth = false;
|
init_mfc_auth = false;
|
||||||
}
|
}
|
||||||
if (!nfc_target_receive_bytes(pnd, abtRx, &szRx, NULL)) {
|
if ((szRx = nfc_target_receive_bytes(pnd, abtRx, sizeof (abtRx), 0)) < 0) {
|
||||||
nfc_perror (pnd, "nfc_target_receive_bytes");
|
nfc_perror (pnd, "nfc_target_receive_bytes");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -179,19 +180,21 @@ main (int argc, char *argv[])
|
||||||
signal (SIGINT, (void (*)()) intr_hdlr);
|
signal (SIGINT, (void (*)()) intr_hdlr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
// Try to open the NFC reader
|
// Try to open the NFC reader
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_open (NULL, NULL);
|
||||||
|
|
||||||
// Display libnfc version
|
// Display libnfc version
|
||||||
acLibnfcVersion = nfc_version ();
|
acLibnfcVersion = nfc_version ();
|
||||||
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
|
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
|
||||||
|
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
ERR("Unable to connect to NFC device");
|
ERR("Unable to open NFC device");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Connected to NFC device: %s\n", pnd->acName);
|
printf ("NFC device: %s opened\n", nfc_device_get_name (pnd));
|
||||||
|
|
||||||
// Notes for ISO14443-A emulated tags:
|
// Notes for ISO14443-A emulated tags:
|
||||||
// * Only short UIDs are supported
|
// * Only short UIDs are supported
|
||||||
|
@ -203,7 +206,7 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
// Example of a Mifare Classic Mini
|
// Example of a Mifare Classic Mini
|
||||||
// Note that crypto1 is not implemented in this example
|
// Note that crypto1 is not implemented in this example
|
||||||
nfc_target_t nt = {
|
nfc_target nt = {
|
||||||
.nm = {
|
.nm = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
.nbr = NBR_UNDEFINED,
|
.nbr = NBR_UNDEFINED,
|
||||||
|
@ -220,40 +223,53 @@ main (int argc, char *argv[])
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
// Example of a FeliCa
|
// Example of a FeliCa
|
||||||
nfc_target_t nt = {
|
nfc_target nt = {
|
||||||
.nm.nmt = NMT_FELICA,
|
.nm = {
|
||||||
.nm.nbr = NBR_UNDEFINED,
|
.nmt = NMT_FELICA,
|
||||||
.nti.nfi.abtId = { 0x01, 0xFE, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF },
|
.nbr = NBR_UNDEFINED,
|
||||||
.nti.nfi.abtPad = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF },
|
},
|
||||||
.nti.nfi.abtSysCode = { 0xFF, 0xFF },
|
.nti = {
|
||||||
|
.nfi = {
|
||||||
|
.abtId = { 0x01, 0xFE, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF },
|
||||||
|
.abtPad = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF },
|
||||||
|
.abtSysCode = { 0xFF, 0xFF },
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
// Example of a ISO14443-4 (DESfire)
|
// Example of a ISO14443-4 (DESfire)
|
||||||
nfc_target_t nt = {
|
nfc_target nt = {
|
||||||
.nm.nmt = NMT_ISO14443A,
|
.nm = {
|
||||||
.nm.nbr = NBR_UNDEFINED,
|
.nmt = NMT_ISO14443A,
|
||||||
.nti.nai.abtAtqa = { 0x03, 0x44 },
|
.nbr = NBR_UNDEFINED,
|
||||||
.nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef },
|
},
|
||||||
.nti.nai.btSak = 0x20,
|
.nti = {
|
||||||
.nti.nai.szUidLen = 4,
|
.nai = {
|
||||||
.nti.nai.abtAts = { 0x75, 0x77, 0x81, 0x02, 0x80 },
|
abtAtqa = { 0x03, 0x44 },
|
||||||
.nti.nai.szAtsLen = 5,
|
abtUid = { 0x08, 0xab, 0xcd, 0xef },
|
||||||
|
btSak = 0x20,
|
||||||
|
.szUidLen = 4,
|
||||||
|
.abtAts = { 0x75, 0x77, 0x81, 0x02, 0x80 },
|
||||||
|
.szAtsLen = 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
printf ("%s will emulate this ISO14443-A tag:\n", argv[0]);
|
printf ("%s will emulate this ISO14443-A tag:\n", argv[0]);
|
||||||
print_nfc_iso14443a_info (nt.nti.nai, true);
|
print_nfc_iso14443a_info (nt.nti.nai, true);
|
||||||
|
|
||||||
// Switch off NDO_EASY_FRAMING if target is not ISO14443-4
|
// Switch off NP_EASY_FRAMING if target is not ISO14443-4
|
||||||
nfc_configure (pnd, NDO_EASY_FRAMING, (nt.nti.nai.btSak & SAK_ISO14443_4_COMPLIANT));
|
nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, (nt.nti.nai.btSak & SAK_ISO14443_4_COMPLIANT));
|
||||||
printf ("NFC device (configured as target) is now emulating the tag, please touch it with a second NFC device (initiator)\n");
|
printf ("NFC device (configured as target) is now emulating the tag, please touch it with a second NFC device (initiator)\n");
|
||||||
if (!nfc_target_emulate_tag (pnd, &nt)) {
|
if (!nfc_target_emulate_tag (pnd, &nt)) {
|
||||||
nfc_perror (pnd, "nfc_target_emulate_tag");
|
nfc_perror (pnd, "nfc_target_emulate_tag");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_disconnect(pnd);
|
nfc_close(pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,14 +56,14 @@
|
||||||
|
|
||||||
#define MAX_FRAME_LEN 264
|
#define MAX_FRAME_LEN 264
|
||||||
|
|
||||||
static byte_t abtRecv[MAX_FRAME_LEN];
|
static uint8_t abtRecv[MAX_FRAME_LEN];
|
||||||
static size_t szRecvBits;
|
static int szRecvBits;
|
||||||
static nfc_device_t *pnd;
|
static nfc_device *pnd;
|
||||||
|
|
||||||
// ISO14443A Anti-Collision response
|
// ISO14443A Anti-Collision response
|
||||||
byte_t abtAtqa[2] = { 0x04, 0x00 };
|
uint8_t abtAtqa[2] = { 0x04, 0x00 };
|
||||||
byte_t abtUidBcc[5] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x62 };
|
uint8_t abtUidBcc[5] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x62 };
|
||||||
byte_t abtSak[9] = { 0x08, 0xb6, 0xdd };
|
uint8_t abtSak[9] = { 0x08, 0xb6, 0xdd };
|
||||||
|
|
||||||
void
|
void
|
||||||
intr_hdlr (void)
|
intr_hdlr (void)
|
||||||
|
@ -88,7 +88,7 @@ print_usage (char *argv[])
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
byte_t *pbtTx = NULL;
|
uint8_t *pbtTx = NULL;
|
||||||
size_t szTxBits;
|
size_t szTxBits;
|
||||||
bool quiet_output = false;
|
bool quiet_output = false;
|
||||||
|
|
||||||
|
@ -104,12 +104,12 @@ main (int argc, char *argv[])
|
||||||
printf ("Quiet mode.\n");
|
printf ("Quiet mode.\n");
|
||||||
quiet_output = true;
|
quiet_output = true;
|
||||||
} else if ((arg == argc - 1) && (strlen (argv[arg]) == 8)) { // See if UID was specified as HEX string
|
} else if ((arg == argc - 1) && (strlen (argv[arg]) == 8)) { // See if UID was specified as HEX string
|
||||||
byte_t abtTmp[3] = { 0x00, 0x00, 0x00 };
|
uint8_t abtTmp[3] = { 0x00, 0x00, 0x00 };
|
||||||
printf ("[+] Using UID: %s\n", argv[arg]);
|
printf ("[+] Using UID: %s\n", argv[arg]);
|
||||||
abtUidBcc[4] = 0x00;
|
abtUidBcc[4] = 0x00;
|
||||||
for (i = 0; i < 4; ++i) {
|
for (i = 0; i < 4; ++i) {
|
||||||
memcpy (abtTmp, argv[arg] + i * 2, 2);
|
memcpy (abtTmp, argv[arg] + i * 2, 2);
|
||||||
abtUidBcc[i] = (byte_t) strtol ((char *) abtTmp, NULL, 16);
|
abtUidBcc[i] = (uint8_t) strtol ((char *) abtTmp, NULL, 16);
|
||||||
abtUidBcc[4] ^= abtUidBcc[i];
|
abtUidBcc[4] ^= abtUidBcc[i];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -125,22 +125,24 @@ main (int argc, char *argv[])
|
||||||
signal (SIGINT, (void (*)()) intr_hdlr);
|
signal (SIGINT, (void (*)()) intr_hdlr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
// Try to open the NFC device
|
// Try to open the NFC device
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_open (NULL, NULL);
|
||||||
|
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
printf ("Unable to connect to NFC device\n");
|
printf ("Unable to open NFC device\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf ("Connected to NFC device: %s\n", pnd->acName);
|
printf ("NFC device: %s opened\n", nfc_device_get_name (pnd));
|
||||||
printf ("[+] Try to break out the auto-emulation, this requires a second NFC device!\n");
|
printf ("[+] Try to break out the auto-emulation, this requires a second NFC device!\n");
|
||||||
printf ("[+] To do this, please send any command after the anti-collision\n");
|
printf ("[+] To do this, please send any command after the anti-collision\n");
|
||||||
printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" or \"nfc-list\" tool.\n");
|
printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" or \"nfc-list\" tool.\n");
|
||||||
|
|
||||||
// Note: We have to build a "fake" nfc_target_t in order to do exactly the same that was done before the new nfc_target_init() was introduced.
|
// Note: We have to build a "fake" nfc_target in order to do exactly the same that was done before the new nfc_target_init() was introduced.
|
||||||
nfc_target_t nt = {
|
nfc_target nt = {
|
||||||
.nm = {
|
.nm = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
.nbr = NBR_UNDEFINED,
|
.nbr = NBR_UNDEFINED,
|
||||||
|
@ -155,16 +157,16 @@ main (int argc, char *argv[])
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if (!nfc_target_init (pnd, &nt, abtRecv, &szRecvBits)) {
|
if ((szRecvBits = nfc_target_init (pnd, &nt, abtRecv, sizeof (abtRecv), 0)) < 0) {
|
||||||
nfc_perror (pnd, "nfc_target_init");
|
nfc_perror (pnd, "nfc_target_init");
|
||||||
ERR ("Could not come out of auto-emulation, no command was received");
|
ERR ("Could not come out of auto-emulation, no command was received");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
printf ("[+] Received initiator command: ");
|
printf ("[+] Received initiator command: ");
|
||||||
print_hex_bits (abtRecv, szRecvBits);
|
print_hex_bits (abtRecv, (size_t) szRecvBits);
|
||||||
printf ("[+] Configuring communication\n");
|
printf ("[+] Configuring communication\n");
|
||||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, false) || !nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
|
if ((nfc_device_set_property_bool (pnd, NP_HANDLE_CRC, false) < 0) || (nfc_device_set_property_bool (pnd, NP_HANDLE_PARITY, true) < 0)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
printf ("[+] Done, the emulated tag is initialized with UID: %02X%02X%02X%02X\n\n", abtUidBcc[0], abtUidBcc[1],
|
printf ("[+] Done, the emulated tag is initialized with UID: %02X%02X%02X%02X\n\n", abtUidBcc[0], abtUidBcc[1],
|
||||||
|
@ -172,7 +174,7 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// Test if we received a frame
|
// Test if we received a frame
|
||||||
if (nfc_target_receive_bits (pnd, abtRecv, &szRecvBits, NULL)) {
|
if ((szRecvBits = nfc_target_receive_bits (pnd, abtRecv, sizeof (abtRecv), 0)) > 0) {
|
||||||
// Prepare the command to send back for the anti-collision request
|
// Prepare the command to send back for the anti-collision request
|
||||||
switch (szRecvBits) {
|
switch (szRecvBits) {
|
||||||
case 7: // Request or Wakeup
|
case 7: // Request or Wakeup
|
||||||
|
@ -200,12 +202,12 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
if (!quiet_output) {
|
if (!quiet_output) {
|
||||||
printf ("R: ");
|
printf ("R: ");
|
||||||
print_hex_bits (abtRecv, szRecvBits);
|
print_hex_bits (abtRecv, (size_t) szRecvBits);
|
||||||
}
|
}
|
||||||
// Test if we know how to respond
|
// Test if we know how to respond
|
||||||
if (szTxBits) {
|
if (szTxBits) {
|
||||||
// Send and print the command to the screen
|
// Send and print the command to the screen
|
||||||
if (!nfc_target_send_bits (pnd, pbtTx, szTxBits, NULL)) {
|
if (nfc_target_send_bits (pnd, pbtTx, szTxBits, NULL) < 0) {
|
||||||
nfc_perror (pnd, "nfc_target_send_bits");
|
nfc_perror (pnd, "nfc_target_send_bits");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -216,10 +218,12 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.TH nfc-poll 1 "June 26, 2009" "libnfc" "libnfc's examples"
|
.TH nfc-poll 1 "June 26, 2009" "libnfc" "libnfc's examples"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
nfc-poll \- Poll for one NFC target
|
nfc-poll \- poll first available NFC target
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B nfc-poll
|
.B nfc-poll
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
@ -8,8 +8,18 @@ nfc-poll \- Poll for one NFC target
|
||||||
is a utility for polling any available target (tags but also NFCIP targets)
|
is a utility for polling any available target (tags but also NFCIP targets)
|
||||||
using ISO14443-A, FeliCa, Jewel and ISO14443-B modulations.
|
using ISO14443-A, FeliCa, Jewel and ISO14443-B modulations.
|
||||||
|
|
||||||
This tool relies on a hardware polling feature of the PN532, it will display
|
This tool uses hardware polling feature if available (ie. PN532) or switch back
|
||||||
available information retrieved from the tag.
|
to software polling, it will display available information retrieved from the
|
||||||
|
tag.
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B \-v
|
||||||
|
Tells
|
||||||
|
.I
|
||||||
|
nfc-poll
|
||||||
|
to be verbose and display detailed information about the targets shown.
|
||||||
|
This includes SAK decoding and fingerprinting is available.
|
||||||
|
|
||||||
.SH IMPORTANT
|
.SH IMPORTANT
|
||||||
There are some well-know limits with this example:
|
There are some well-know limits with this example:
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
|
|
||||||
#define MAX_DEVICE_COUNT 16
|
#define MAX_DEVICE_COUNT 16
|
||||||
|
|
||||||
static nfc_device_t *pnd = NULL;
|
static nfc_device *pnd = NULL;
|
||||||
|
|
||||||
void stop_polling (int sig)
|
void stop_polling (int sig)
|
||||||
{
|
{
|
||||||
|
@ -62,80 +62,76 @@ void stop_polling (int sig)
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_usage (const char* progname)
|
||||||
|
{
|
||||||
|
printf ("usage: %s [-v]\n", progname);
|
||||||
|
printf (" -v\t verbose display\n");
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, const char *argv[])
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
size_t szFound;
|
|
||||||
size_t i;
|
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
nfc_device_desc_t *pnddDevices;
|
|
||||||
|
|
||||||
signal (SIGINT, stop_polling);
|
signal (SIGINT, stop_polling);
|
||||||
|
|
||||||
pnddDevices = parse_args (argc, argv, &szFound, &verbose);
|
|
||||||
|
|
||||||
// Display libnfc version
|
// Display libnfc version
|
||||||
const char *acLibnfcVersion = nfc_version ();
|
const char *acLibnfcVersion = nfc_version ();
|
||||||
|
|
||||||
if (argc > 1) {
|
|
||||||
errx (1, "usage: %s", argv[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
|
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
|
||||||
|
if (argc != 1) {
|
||||||
if (szFound == 0) {
|
if ((argc == 2) && (0 == strcmp ("-v", argv[1]))) {
|
||||||
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
|
verbose = true;
|
||||||
fprintf (stderr, "malloc() failed\n");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound);
|
|
||||||
|
|
||||||
if (szFound == 0) {
|
|
||||||
printf ("No NFC device found.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < szFound; i++) {
|
|
||||||
const uint8_t uiPollNr = 20;
|
|
||||||
const uint8_t uiPeriod = 2;
|
|
||||||
const nfc_modulation_t nmModulations[5] = {
|
|
||||||
{ .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 },
|
|
||||||
};
|
|
||||||
const size_t szModulations = 5;
|
|
||||||
|
|
||||||
nfc_target_t nt;
|
|
||||||
bool res;
|
|
||||||
|
|
||||||
pnd = nfc_connect (&(pnddDevices[i]));
|
|
||||||
|
|
||||||
if (pnd == NULL) {
|
|
||||||
ERR ("%s", "Unable to connect to NFC device.");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
nfc_initiator_init (pnd);
|
|
||||||
|
|
||||||
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
|
||||||
printf ("NFC device will poll during %ld ms (%u pollings of %lu ms for %zd modulations)\n", (unsigned long) uiPollNr * szModulations * uiPeriod * 150, uiPollNr, (unsigned long) uiPeriod * 150, szModulations);
|
|
||||||
res = nfc_initiator_poll_target (pnd, nmModulations, szModulations, uiPollNr, uiPeriod, &nt);
|
|
||||||
if (res) {
|
|
||||||
print_nfc_target ( nt, verbose );
|
|
||||||
} else {
|
} else {
|
||||||
if (pnd->iLastError) {
|
print_usage (argv[0]);
|
||||||
nfc_perror (pnd, "nfc_initiator_poll_targets");
|
exit (EXIT_FAILURE);
|
||||||
nfc_disconnect (pnd);
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
} else {
|
|
||||||
printf ("No target found.\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
nfc_disconnect (pnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free (pnddDevices);
|
const uint8_t uiPollNr = 20;
|
||||||
|
const uint8_t uiPeriod = 2;
|
||||||
|
const nfc_modulation nmModulations[5] = {
|
||||||
|
{ .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 },
|
||||||
|
};
|
||||||
|
const size_t szModulations = 5;
|
||||||
|
|
||||||
|
nfc_target nt;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
|
pnd = nfc_open (NULL, NULL);
|
||||||
|
|
||||||
|
if (pnd == NULL) {
|
||||||
|
ERR ("%s", "Unable to open NFC device.");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nfc_initiator_init (pnd) < 0) {
|
||||||
|
nfc_perror (pnd, "nfc_initiator_init");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("NFC reader: %s opened\n", nfc_device_get_name (pnd));
|
||||||
|
printf ("NFC device will poll during %ld ms (%u pollings of %lu ms for %zd modulations)\n", (unsigned long) uiPollNr * szModulations * uiPeriod * 150, uiPollNr, (unsigned long) uiPeriod * 150, szModulations);
|
||||||
|
if ((res = nfc_initiator_poll_target (pnd, nmModulations, szModulations, uiPollNr, uiPeriod, &nt)) < 0) {
|
||||||
|
nfc_perror (pnd, "nfc_initiator_poll_target");
|
||||||
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res > 0) {
|
||||||
|
print_nfc_target ( nt, verbose );
|
||||||
|
} else {
|
||||||
|
printf ("No target found.\n");
|
||||||
|
}
|
||||||
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,14 +50,14 @@
|
||||||
#define MAX_FRAME_LEN 264
|
#define MAX_FRAME_LEN 264
|
||||||
#define MAX_DEVICE_COUNT 2
|
#define MAX_DEVICE_COUNT 2
|
||||||
|
|
||||||
static byte_t abtReaderRx[MAX_FRAME_LEN];
|
static uint8_t abtReaderRx[MAX_FRAME_LEN];
|
||||||
static byte_t abtReaderRxPar[MAX_FRAME_LEN];
|
static uint8_t abtReaderRxPar[MAX_FRAME_LEN];
|
||||||
static size_t szReaderRxBits;
|
static int szReaderRxBits;
|
||||||
static byte_t abtTagRx[MAX_FRAME_LEN];
|
static uint8_t abtTagRx[MAX_FRAME_LEN];
|
||||||
static byte_t abtTagRxPar[MAX_FRAME_LEN];
|
static uint8_t abtTagRxPar[MAX_FRAME_LEN];
|
||||||
static size_t szTagRxBits;
|
static int szTagRxBits;
|
||||||
static nfc_device_t *pndReader;
|
static nfc_device *pndReader;
|
||||||
static nfc_device_t *pndTag;
|
static nfc_device *pndTag;
|
||||||
static bool quitting = false;
|
static bool quitting = false;
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -82,8 +82,6 @@ main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int arg;
|
int arg;
|
||||||
bool quiet_output = false;
|
bool quiet_output = false;
|
||||||
size_t szFound;
|
|
||||||
nfc_device_desc_t *pnddDevices;
|
|
||||||
const char *acLibnfcVersion = nfc_version ();
|
const char *acLibnfcVersion = nfc_version ();
|
||||||
|
|
||||||
// Get commandline options
|
// Get commandline options
|
||||||
|
@ -109,33 +107,32 @@ main (int argc, char *argv[])
|
||||||
signal (SIGINT, (void (*)()) intr_hdlr);
|
signal (SIGINT, (void (*)()) intr_hdlr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Allocate memory to put the result of available devices listing
|
nfc_connstring connstrings[MAX_DEVICE_COUNT];
|
||||||
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
|
|
||||||
fprintf (stderr, "malloc() failed\n");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
// List available devices
|
// List available devices
|
||||||
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound);
|
size_t szFound = nfc_list_devices (NULL, connstrings, MAX_DEVICE_COUNT);
|
||||||
|
|
||||||
if (szFound < 2) {
|
if (szFound < 2) {
|
||||||
ERR ("%zd device found but two connected devices are needed to relay NFC.", szFound);
|
ERR ("%zd device found but two opened devices are needed to relay NFC.", szFound);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
// Try to open the NFC emulator device
|
// Try to open the NFC emulator device
|
||||||
pndTag = nfc_connect (&(pnddDevices[0]));
|
pndTag = nfc_open (NULL, connstrings[0]);
|
||||||
if (pndTag == NULL) {
|
if (pndTag == NULL) {
|
||||||
printf ("Error connecting NFC emulator device\n");
|
printf ("Error opening NFC emulator device\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Hint: tag <---> initiator (relay) <---> target (relay) <---> original reader\n\n");
|
printf ("Hint: tag <---> initiator (relay) <---> target (relay) <---> original reader\n\n");
|
||||||
|
|
||||||
printf ("Connected to the NFC emulator device: %s\n", pndTag->acName);
|
printf ("NFC emulator device: %s opened\n", nfc_device_get_name (pndTag));
|
||||||
printf ("[+] Try to break out the auto-emulation, this requires a second reader!\n");
|
printf ("[+] Try to break out the auto-emulation, this requires a second reader!\n");
|
||||||
printf ("[+] To do this, please send any command after the anti-collision\n");
|
printf ("[+] To do this, please send any command after the anti-collision\n");
|
||||||
printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
|
printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
|
||||||
|
|
||||||
nfc_target_t nt = {
|
nfc_target nt = {
|
||||||
.nm = {
|
.nm = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
.nbr = NBR_UNDEFINED,
|
.nbr = NBR_UNDEFINED,
|
||||||
|
@ -151,60 +148,65 @@ main (int argc, char *argv[])
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!nfc_target_init (pndTag, &nt, abtReaderRx, &szReaderRxBits)) {
|
if ((szReaderRxBits = nfc_target_init (pndTag, &nt, abtReaderRx, sizeof (abtReaderRx), 0)) < 0) {
|
||||||
ERR ("%s", "Initialization of NFC emulator failed");
|
ERR ("%s", "Initialization of NFC emulator failed");
|
||||||
nfc_disconnect (pndTag);
|
nfc_close (pndTag);
|
||||||
|
nfc_exit (NULL);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf ("%s", "Configuring emulator settings...");
|
printf ("%s", "Configuring emulator settings...");
|
||||||
if (!nfc_configure (pndTag, NDO_HANDLE_CRC, false) ||
|
if ((nfc_device_set_property_bool (pndTag, NP_HANDLE_CRC, false) < 0) ||
|
||||||
!nfc_configure (pndTag, NDO_HANDLE_PARITY, false) || !nfc_configure (pndTag, NDO_ACCEPT_INVALID_FRAMES, true)) {
|
(nfc_device_set_property_bool (pndTag, NP_HANDLE_PARITY, false) < 0) || (nfc_device_set_property_bool (pndTag, NP_ACCEPT_INVALID_FRAMES, true)) < 0) {
|
||||||
nfc_perror (pndTag, "nfc_configure");
|
nfc_perror (pndTag, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
printf ("%s", "Done, emulated tag is initialized");
|
printf ("%s", "Done, emulated tag is initialized");
|
||||||
|
|
||||||
// Try to open the NFC reader
|
// Try to open the NFC reader
|
||||||
pndReader = nfc_connect (&(pnddDevices[1]));
|
pndReader = nfc_open (NULL, connstrings[1]);
|
||||||
|
|
||||||
printf ("Connected to the NFC reader device: %s", pndReader->acName);
|
printf ("NFC reader device: %s opened", nfc_device_get_name (pndReader));
|
||||||
printf ("%s", "Configuring NFC reader settings...");
|
printf ("%s", "Configuring NFC reader settings...");
|
||||||
nfc_initiator_init (pndReader);
|
|
||||||
if (!nfc_configure (pndReader, NDO_HANDLE_CRC, false) ||
|
if (nfc_initiator_init (pndReader) < 0) {
|
||||||
!nfc_configure (pndReader, NDO_HANDLE_PARITY, false) ||
|
nfc_perror (pndReader, "nfc_initiator_init");
|
||||||
!nfc_configure (pndReader, NDO_ACCEPT_INVALID_FRAMES, true)) {
|
exit (EXIT_FAILURE);
|
||||||
nfc_perror (pndReader, "nfc_configure");
|
}
|
||||||
|
if ((nfc_device_set_property_bool (pndReader, NP_HANDLE_CRC, false) < 0) ||
|
||||||
|
(nfc_device_set_property_bool (pndReader, NP_HANDLE_PARITY, false) < 0) ||
|
||||||
|
(nfc_device_set_property_bool (pndReader, NP_ACCEPT_INVALID_FRAMES, true)) < 0) {
|
||||||
|
nfc_perror (pndReader, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
printf ("%s", "Done, relaying frames now!");
|
printf ("%s", "Done, relaying frames now!");
|
||||||
|
|
||||||
while (!quitting) {
|
while (!quitting) {
|
||||||
// Test if we received a frame from the reader
|
// Test if we received a frame from the reader
|
||||||
if (nfc_target_receive_bits (pndTag, abtReaderRx, &szReaderRxBits, abtReaderRxPar)) {
|
if ((szReaderRxBits = nfc_target_receive_bits (pndTag, abtReaderRx, sizeof (abtReaderRx), abtReaderRxPar)) > 0) {
|
||||||
// Drop down the field before sending a REQA command and start a new session
|
// Drop down the field before sending a REQA command and start a new session
|
||||||
if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26) {
|
if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26) {
|
||||||
// Drop down field for a very short time (original tag will reboot)
|
// Drop down field for a very short time (original tag will reboot)
|
||||||
if (!nfc_configure (pndReader, NDO_ACTIVATE_FIELD, false)) {
|
if (nfc_device_set_property_bool (pndReader, NP_ACTIVATE_FIELD, false) < 0) {
|
||||||
nfc_perror (pndReader, "nfc_configure");
|
nfc_perror (pndReader, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (!quiet_output)
|
if (!quiet_output)
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
if (!nfc_configure (pndReader, NDO_ACTIVATE_FIELD, true)) {
|
if (nfc_device_set_property_bool (pndReader, NP_ACTIVATE_FIELD, true) < 0) {
|
||||||
nfc_perror (pndReader, "nfc_configure");
|
nfc_perror (pndReader, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Print the reader frame to the screen
|
// Print the reader frame to the screen
|
||||||
if (!quiet_output) {
|
if (!quiet_output) {
|
||||||
printf ("R: ");
|
printf ("R: ");
|
||||||
print_hex_par (abtReaderRx, szReaderRxBits, abtReaderRxPar);
|
print_hex_par (abtReaderRx, (size_t) szReaderRxBits, abtReaderRxPar);
|
||||||
}
|
}
|
||||||
// Forward the frame to the original tag
|
// Forward the frame to the original tag
|
||||||
if (nfc_initiator_transceive_bits
|
if ((szTagRxBits = nfc_initiator_transceive_bits
|
||||||
(pndReader, abtReaderRx, szReaderRxBits, abtReaderRxPar, abtTagRx, &szTagRxBits, abtTagRxPar)) {
|
(pndReader, abtReaderRx, (size_t) szReaderRxBits, abtReaderRxPar, abtTagRx, abtTagRxPar)) > 0) {
|
||||||
// Redirect the answer back to the reader
|
// Redirect the answer back to the reader
|
||||||
if (!nfc_target_send_bits (pndTag, abtTagRx, szTagRxBits, abtTagRxPar)) {
|
if (nfc_target_send_bits (pndTag, abtTagRx, szTagRxBits, abtTagRxPar) < 0) {
|
||||||
nfc_perror (pndTag, "nfc_target_send_bits");
|
nfc_perror (pndTag, "nfc_target_send_bits");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -217,7 +219,8 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_disconnect (pndTag);
|
nfc_close (pndTag);
|
||||||
nfc_disconnect (pndReader);
|
nfc_close (pndReader);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,49 +52,48 @@
|
||||||
int
|
int
|
||||||
main (int argc, const char *argv[])
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
size_t szFound;
|
|
||||||
size_t i;
|
size_t i;
|
||||||
nfc_device_t *pnd;
|
nfc_device *pnd;
|
||||||
nfc_device_desc_t *pnddDevices;
|
|
||||||
const char *acLibnfcVersion;
|
const char *acLibnfcVersion;
|
||||||
bool result;
|
bool result;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||||
size_t szRx = sizeof(abtRx);
|
size_t szRx = sizeof(abtRx);
|
||||||
const byte_t pncmd_diagnose_communication_line_test[] = { Diagnose, 0x00, 0x06, 'l', 'i', 'b', 'n', 'f', 'c' };
|
const uint8_t pncmd_diagnose_communication_line_test[] = { Diagnose, 0x00, 0x06, 'l', 'i', 'b', 'n', 'f', 'c' };
|
||||||
const byte_t pncmd_diagnose_rom_test[] = { Diagnose, 0x01 };
|
const uint8_t pncmd_diagnose_rom_test[] = { Diagnose, 0x01 };
|
||||||
const byte_t pncmd_diagnose_ram_test[] = { Diagnose, 0x02 };
|
const uint8_t pncmd_diagnose_ram_test[] = { Diagnose, 0x02 };
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
errx (1, "usage: %s", argv[0]);
|
errx (1, "usage: %s", argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
// Display libnfc version
|
// Display libnfc version
|
||||||
acLibnfcVersion = nfc_version ();
|
acLibnfcVersion = nfc_version ();
|
||||||
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
|
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
|
||||||
|
|
||||||
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
|
nfc_connstring connstrings[MAX_DEVICE_COUNT];
|
||||||
fprintf (stderr, "malloc() failed\n");
|
size_t szFound = nfc_list_devices (NULL, connstrings, MAX_DEVICE_COUNT);
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound);
|
|
||||||
|
|
||||||
if (szFound == 0) {
|
if (szFound == 0) {
|
||||||
printf ("No NFC device found.\n");
|
printf ("No NFC device found.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < szFound; i++) {
|
for (i = 0; i < szFound; i++) {
|
||||||
pnd = nfc_connect (&(pnddDevices[i]));
|
pnd = nfc_open (NULL, connstrings[i]);
|
||||||
|
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
ERR ("%s", "Unable to connect to NFC device.");
|
ERR ("%s", "Unable to open NFC device.");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("NFC device [%s] connected.\n", pnd->acName);
|
printf ("NFC device [%s] opened.\n", nfc_device_get_name (pnd));
|
||||||
|
|
||||||
result = pn53x_transceive (pnd, pncmd_diagnose_communication_line_test, sizeof (pncmd_diagnose_communication_line_test), abtRx, &szRx, NULL);
|
res = pn53x_transceive (pnd, pncmd_diagnose_communication_line_test, sizeof (pncmd_diagnose_communication_line_test), abtRx, szRx, 0);
|
||||||
if (result) {
|
if (res > 0) {
|
||||||
|
szRx = (size_t) res;
|
||||||
// Result of Diagnose ping for RC-S360 doesn't contain status byte so we've to handle both cases
|
// Result of Diagnose ping for RC-S360 doesn't contain status byte so we've to handle both cases
|
||||||
result = (memcmp (pncmd_diagnose_communication_line_test + 1, abtRx, sizeof (pncmd_diagnose_communication_line_test) - 1) == 0) ||
|
result = (memcmp (pncmd_diagnose_communication_line_test + 1, abtRx, sizeof (pncmd_diagnose_communication_line_test) - 1) == 0) ||
|
||||||
(memcmp (pncmd_diagnose_communication_line_test + 2, abtRx, sizeof (pncmd_diagnose_communication_line_test) - 2) == 0);
|
(memcmp (pncmd_diagnose_communication_line_test + 2, abtRx, sizeof (pncmd_diagnose_communication_line_test) - 2) == 0);
|
||||||
|
@ -103,16 +102,18 @@ main (int argc, const char *argv[])
|
||||||
}
|
}
|
||||||
printf (" Communication line test: %s\n", result ? "OK" : "Failed");
|
printf (" Communication line test: %s\n", result ? "OK" : "Failed");
|
||||||
|
|
||||||
result = pn53x_transceive (pnd, pncmd_diagnose_rom_test, sizeof (pncmd_diagnose_rom_test), abtRx, &szRx, NULL);
|
res = pn53x_transceive (pnd, pncmd_diagnose_rom_test, sizeof (pncmd_diagnose_rom_test), abtRx, szRx, 0);
|
||||||
if (result) {
|
if (res > 0) {
|
||||||
|
szRx = (size_t) res;
|
||||||
result = ((szRx == 1) && (abtRx[0] == 0x00));
|
result = ((szRx == 1) && (abtRx[0] == 0x00));
|
||||||
} else {
|
} else {
|
||||||
nfc_perror (pnd, "pn53x_transceive");
|
nfc_perror (pnd, "pn53x_transceive");
|
||||||
}
|
}
|
||||||
printf (" ROM test: %s\n", result ? "OK" : "Failed");
|
printf (" ROM test: %s\n", result ? "OK" : "Failed");
|
||||||
|
|
||||||
result = pn53x_transceive (pnd, pncmd_diagnose_ram_test, sizeof (pncmd_diagnose_ram_test), abtRx, &szRx, NULL);
|
res = pn53x_transceive (pnd, pncmd_diagnose_ram_test, sizeof (pncmd_diagnose_ram_test), abtRx, szRx, 0);
|
||||||
if (result) {
|
if (res > 0) {
|
||||||
|
szRx = (size_t) res;
|
||||||
result = ((szRx == 1) && (abtRx[0] == 0x00));
|
result = ((szRx == 1) && (abtRx[0] == 0x00));
|
||||||
} else {
|
} else {
|
||||||
nfc_perror (pnd, "pn53x_transceive");
|
nfc_perror (pnd, "pn53x_transceive");
|
||||||
|
|
|
@ -72,24 +72,26 @@ wait_one_minute (void)
|
||||||
int
|
int
|
||||||
main (int argc, const char *argv[])
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
nfc_device_t *pnd;
|
nfc_device *pnd;
|
||||||
|
|
||||||
(void) argc;
|
(void) argc;
|
||||||
(void) argv;
|
(void) argv;
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
// Display libnfc version
|
// Display libnfc version
|
||||||
const char *acLibnfcVersion = nfc_version ();
|
const char *acLibnfcVersion = nfc_version ();
|
||||||
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
|
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
|
||||||
|
|
||||||
// Connect using the first available NFC device
|
// Open using the first available NFC device
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_open (NULL, NULL);
|
||||||
|
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
ERR ("%s", "Unable to connect to NFC device.");
|
ERR ("%s", "Unable to open NFC device.");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Connected to NFC device: %s\n", pnd->acName);
|
printf ("NFC device: %s opened\n", nfc_device_get_name (pnd));
|
||||||
|
|
||||||
// Print the example's menu
|
// Print the example's menu
|
||||||
printf ("\nSelect the communication mode:\n");
|
printf ("\nSelect the communication mode:\n");
|
||||||
|
@ -110,7 +112,7 @@ main (int argc, const char *argv[])
|
||||||
|
|
||||||
// Connect with the SAM
|
// Connect with the SAM
|
||||||
// FIXME: Its a private pn53x function
|
// FIXME: Its a private pn53x function
|
||||||
if (!pn53x_SAMConfiguration (pnd, mode, NULL)) {
|
if (pn53x_SAMConfiguration (pnd, mode, 0) < 0) {
|
||||||
nfc_perror (pnd, "pn53x_SAMConfiguration");
|
nfc_perror (pnd, "pn53x_SAMConfiguration");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -125,22 +127,25 @@ main (int argc, const char *argv[])
|
||||||
|
|
||||||
case PSM_WIRED_CARD:
|
case PSM_WIRED_CARD:
|
||||||
{
|
{
|
||||||
nfc_target_t nt;
|
nfc_target nt;
|
||||||
|
|
||||||
// Set connected NFC device to initiator mode
|
// Set opened NFC device to initiator mode
|
||||||
nfc_initiator_init (pnd);
|
if (nfc_initiator_init (pnd) < 0) {
|
||||||
|
nfc_perror (pnd, "nfc_initiator_init");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
// Let the reader only try once to find a tag
|
// Let the reader only try once to find a tag
|
||||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
if (nfc_device_set_property_bool (pnd, NP_INFINITE_SELECT, false) < 0) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
// Read the SAM's info
|
// Read the SAM's info
|
||||||
const nfc_modulation_t nmSAM = {
|
const nfc_modulation nmSAM = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
.nbr = NBR_106,
|
.nbr = NBR_106,
|
||||||
};
|
};
|
||||||
if (!nfc_initiator_select_passive_target (pnd, nmSAM, NULL, 0, &nt)) {
|
if (nfc_initiator_select_passive_target (pnd, nmSAM, NULL, 0, &nt) < 0) {
|
||||||
nfc_perror (pnd, "nfc_initiator_select_passive_target");
|
nfc_perror (pnd, "nfc_initiator_select_passive_target");
|
||||||
ERR ("%s", "Reading of SAM info failed.");
|
ERR ("%s", "Reading of SAM info failed.");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
|
@ -153,10 +158,9 @@ main (int argc, const char *argv[])
|
||||||
|
|
||||||
case PSM_DUAL_CARD:
|
case PSM_DUAL_CARD:
|
||||||
{
|
{
|
||||||
byte_t abtRx[MAX_FRAME_LEN];
|
uint8_t abtRx[MAX_FRAME_LEN];
|
||||||
size_t szRx = sizeof(abtRx);
|
|
||||||
|
|
||||||
nfc_target_t nt = {
|
nfc_target nt = {
|
||||||
.nm = {
|
.nm = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
.nbr = NBR_UNDEFINED,
|
.nbr = NBR_UNDEFINED,
|
||||||
|
@ -173,7 +177,7 @@ main (int argc, const char *argv[])
|
||||||
};
|
};
|
||||||
printf ("Now both, NFC device (configured as target) and SAM are readables from an external NFC initiator.\n");
|
printf ("Now both, NFC device (configured as target) and SAM are readables from an external NFC initiator.\n");
|
||||||
printf ("Please note that NFC device (configured as target) stay in target mode until it receive RATS, ATR_REQ or proprietary command.\n");
|
printf ("Please note that NFC device (configured as target) stay in target mode until it receive RATS, ATR_REQ or proprietary command.\n");
|
||||||
if (!nfc_target_init (pnd, &nt, abtRx, &szRx)) {
|
if (nfc_target_init (pnd, &nt, abtRx, sizeof(abtRx), 0) < 0) {
|
||||||
nfc_perror(pnd, "nfc_target_init");
|
nfc_perror(pnd, "nfc_target_init");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -185,10 +189,11 @@ main (int argc, const char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disconnect from the SAM
|
// Disconnect from the SAM
|
||||||
pn53x_SAMConfiguration (pnd, PSM_NORMAL, NULL);
|
pn53x_SAMConfiguration (pnd, PSM_NORMAL, 0);
|
||||||
|
|
||||||
// Disconnect from NFC device
|
// Close NFC device
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
|
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,41 +71,46 @@
|
||||||
|
|
||||||
int main(int argc, const char* argv[])
|
int main(int argc, const char* argv[])
|
||||||
{
|
{
|
||||||
nfc_device_t* pnd;
|
nfc_device *pnd;
|
||||||
byte_t abtRx[MAX_FRAME_LEN];
|
uint8_t abtRx[MAX_FRAME_LEN];
|
||||||
byte_t abtTx[MAX_FRAME_LEN];
|
uint8_t abtTx[MAX_FRAME_LEN];
|
||||||
size_t szRx = sizeof(abtRx);
|
size_t szRx = sizeof(abtRx);
|
||||||
size_t szTx;
|
size_t szTx;
|
||||||
extern FILE* stdin;
|
extern FILE* stdin;
|
||||||
FILE* input = NULL;
|
FILE* input = NULL;
|
||||||
|
|
||||||
if (argc >= 2) {
|
if (argc >= 2) {
|
||||||
if((input=fopen(argv[1], "r"))==NULL) {
|
if((input = fopen(argv[1], "r"))==NULL) {
|
||||||
ERR ("%s", "Cannot open file.");
|
ERR ("%s", "Cannot open file.");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
// Try to open the NFC reader
|
// Try to open the NFC reader
|
||||||
pnd = nfc_connect(NULL);
|
pnd = nfc_open(NULL, NULL);
|
||||||
|
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
ERR ("%s", "Unable to connect to NFC device.");
|
ERR ("%s", "Unable to open NFC device.");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
printf ("NFC reader: %s opened\n", nfc_device_get_name (pnd));
|
||||||
nfc_initiator_init(pnd);
|
if (nfc_initiator_init (pnd) < 0) {
|
||||||
|
nfc_perror (pnd, "nfc_initiator_init");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
char * cmd;
|
char *cmd;
|
||||||
char * prompt="> ";
|
char *prompt = "> ";
|
||||||
while(1) {
|
while(1) {
|
||||||
int offset=0;
|
int offset = 0;
|
||||||
#if defined(HAVE_READLINE)
|
#if defined(HAVE_READLINE)
|
||||||
if (input==NULL) { // means we use stdin
|
if (input == NULL) { // means we use stdin
|
||||||
cmd=readline(prompt);
|
cmd = readline(prompt);
|
||||||
// NULL if ctrl-d
|
// NULL if ctrl-d
|
||||||
if (cmd==NULL) {
|
if (cmd == NULL) {
|
||||||
printf("Bye!\n");
|
printf("Bye!\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -113,7 +118,7 @@ int main(int argc, const char* argv[])
|
||||||
} else {
|
} else {
|
||||||
#endif //HAVE_READLINE
|
#endif //HAVE_READLINE
|
||||||
size_t n = 255;
|
size_t n = 255;
|
||||||
char * ret = NULL;
|
char *ret = NULL;
|
||||||
cmd = malloc(n);
|
cmd = malloc(n);
|
||||||
printf("%s", prompt);
|
printf("%s", prompt);
|
||||||
fflush(0);
|
fflush(0);
|
||||||
|
@ -132,18 +137,18 @@ int main(int argc, const char* argv[])
|
||||||
#if defined(HAVE_READLINE)
|
#if defined(HAVE_READLINE)
|
||||||
}
|
}
|
||||||
#endif //HAVE_READLINE
|
#endif //HAVE_READLINE
|
||||||
if (cmd[0]=='q') {
|
if (cmd[0] == 'q') {
|
||||||
printf("Bye!\n");
|
printf("Bye!\n");
|
||||||
free(cmd);
|
free(cmd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cmd[0]=='p') {
|
if (cmd[0] == 'p') {
|
||||||
int s=0;
|
int s = 0;
|
||||||
offset++;
|
offset++;
|
||||||
while (isspace(cmd[offset])) {
|
while (isspace(cmd[offset])) {
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
sscanf(cmd+offset, "%d", &s);
|
sscanf(cmd + offset, "%d", &s);
|
||||||
printf("Pause for %i msecs\n", s);
|
printf("Pause for %i msecs\n", s);
|
||||||
if (s>0) {
|
if (s>0) {
|
||||||
sleep(s * SUSP_TIME);
|
sleep(s * SUSP_TIME);
|
||||||
|
@ -152,14 +157,14 @@ int main(int argc, const char* argv[])
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
szTx = 0;
|
szTx = 0;
|
||||||
for(int i = 0; i<MAX_FRAME_LEN-10; i++) {
|
for(int i = 0; i < MAX_FRAME_LEN - 10; i++) {
|
||||||
int size;
|
int size;
|
||||||
byte_t byte;
|
uint8_t byte;
|
||||||
while (isspace(cmd[offset])) {
|
while (isspace(cmd[offset])) {
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
size = sscanf(cmd+offset, "%2x", (unsigned int*)&byte);
|
size = sscanf(cmd+offset, "%2x", (unsigned int*)&byte);
|
||||||
if (size<1) {
|
if (size < 1 ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
abtTx[i] = byte;
|
abtTx[i] = byte;
|
||||||
|
@ -175,14 +180,16 @@ int main(int argc, const char* argv[])
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
printf("Tx: ");
|
printf("Tx: ");
|
||||||
print_hex((byte_t*)abtTx,szTx);
|
print_hex((uint8_t*)abtTx,szTx);
|
||||||
|
|
||||||
szRx = sizeof(abtRx);
|
szRx = sizeof(abtRx);
|
||||||
if (!pn53x_transceive (pnd, abtTx, szTx, abtRx, &szRx, NULL)) {
|
int res = 0;
|
||||||
|
if ((res = pn53x_transceive (pnd, abtTx, szTx, abtRx, szRx, 0)) < 0) {
|
||||||
free(cmd);
|
free(cmd);
|
||||||
nfc_perror (pnd, "Rx");
|
nfc_perror (pnd, "Rx");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
szRx = (size_t) res;
|
||||||
|
|
||||||
printf("Rx: ");
|
printf("Rx: ");
|
||||||
print_hex(abtRx, szRx);
|
print_hex(abtRx, szRx);
|
||||||
|
@ -192,6 +199,7 @@ int main(int argc, const char* argv[])
|
||||||
if (input != NULL) {
|
if (input != NULL) {
|
||||||
fclose(input);
|
fclose(input);
|
||||||
}
|
}
|
||||||
nfc_disconnect(pnd);
|
nfc_close(pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,17 +32,17 @@ struct nfc_emulation_state_machine;
|
||||||
|
|
||||||
|
|
||||||
struct nfc_emulator {
|
struct nfc_emulator {
|
||||||
nfc_target_t *target;
|
nfc_target *target;
|
||||||
struct nfc_emulation_state_machine *state_machine;
|
struct nfc_emulation_state_machine *state_machine;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nfc_emulation_state_machine {
|
struct nfc_emulation_state_machine {
|
||||||
int (*io)(struct nfc_emulator *emulator, const byte_t *data_in, const size_t data_in_len, byte_t *data_out, const size_t data_out_len);
|
int (*io)(struct nfc_emulator *emulator, const uint8_t *data_in, const size_t data_in_len, uint8_t *data_out, const size_t data_out_len);
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
NFC_EXPORT int nfc_emulate_target (nfc_device_t* pnd, struct nfc_emulator *emulator);
|
NFC_EXPORT int nfc_emulate_target (nfc_device* pnd, struct nfc_emulator *emulator);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,80 +32,48 @@
|
||||||
# include <stdbool.h>
|
# include <stdbool.h>
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
|
|
||||||
typedef uint8_t byte_t;
|
typedef void *nfc_context;
|
||||||
|
|
||||||
# define DEVICE_NAME_LENGTH 256
|
|
||||||
# define DEVICE_PORT_LENGTH 64
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct nfc_device_t
|
* NFC device
|
||||||
* @brief NFC device information
|
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct nfc_device nfc_device;
|
||||||
/** Driver's functions for handling device specific wrapping */
|
|
||||||
const struct nfc_driver_t *driver;
|
|
||||||
void* driver_data;
|
|
||||||
void* chip_data;
|
|
||||||
|
|
||||||
/** Device name string, including device wrapper firmware */
|
|
||||||
char acName[DEVICE_NAME_LENGTH];
|
|
||||||
/** Is the crc automaticly added, checked and removed from the frames */
|
|
||||||
bool bCrc;
|
|
||||||
/** Does the chip handle parity bits, all parities are handled as data */
|
|
||||||
bool bPar;
|
|
||||||
/** Should the chip handle frames encapsulation and chaining */
|
|
||||||
bool bEasyFraming;
|
|
||||||
/** Should the chip switch automatically activate ISO14443-4 when
|
|
||||||
selecting tags supporting it? */
|
|
||||||
bool bAutoIso14443_4;
|
|
||||||
/** Supported modulation encoded in a byte */
|
|
||||||
byte_t btSupportByte;
|
|
||||||
/** Last error reported by the PCD / encountered by the PCD driver
|
|
||||||
* MSB LSB
|
|
||||||
* | 00 | 00 |
|
|
||||||
* || ||
|
|
||||||
* || ++----- Chip-level error (as reported by the PCD)
|
|
||||||
* |+---------- Driver-level specific error
|
|
||||||
* +----------- Driver-level general error (common to all drivers)
|
|
||||||
*/
|
|
||||||
int iLastError;
|
|
||||||
} nfc_device_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct nfc_device_desc_t
|
* Connection string
|
||||||
* @brief NFC device description
|
|
||||||
*
|
|
||||||
* This struct is used to try to connect to a specified nfc device when nfc_connect(...)
|
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef char nfc_connstring[1024];
|
||||||
/** Device name (e.g. "ACS ACR 38U-CCID 00 00") */
|
|
||||||
char acDevice[DEVICE_NAME_LENGTH];
|
|
||||||
/** Driver name (e.g. "PN532_UART")*/
|
|
||||||
char *pcDriver;
|
|
||||||
/** Port (e.g. "/dev/ttyUSB0") */
|
|
||||||
char acPort[DEVICE_PORT_LENGTH];
|
|
||||||
/** Port speed (e.g. "115200") */
|
|
||||||
uint32_t uiSpeed;
|
|
||||||
/** Device index for backward compatibility (used to choose one specific device in USB or PSCS devices list) */
|
|
||||||
uint32_t uiBusIndex;
|
|
||||||
} nfc_device_desc_t;
|
|
||||||
|
|
||||||
// Compiler directive, set struct alignment to 1 byte_t for compatibility
|
|
||||||
# pragma pack(1)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum nfc_device_option_t
|
* Properties
|
||||||
* @brief NFC device option
|
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/** Let the PN53X chip handle the CRC bytes. This means that the chip appends
|
/**
|
||||||
|
* Default command processing timeout
|
||||||
|
* Property value's (duration) unit is ms and 0 means no timeout (infinite).
|
||||||
|
* Default value is set by driver layer
|
||||||
|
*/
|
||||||
|
NP_TIMEOUT_COMMAND,
|
||||||
|
/**
|
||||||
|
* Timeout between ATR_REQ and ATR_RES
|
||||||
|
* When the device is in initiator mode, a target is considered as mute if no
|
||||||
|
* valid ATR_RES is received within this timeout value.
|
||||||
|
* Default value for this property is 103 ms on PN53x based devices.
|
||||||
|
*/
|
||||||
|
NP_TIMEOUT_ATR,
|
||||||
|
/**
|
||||||
|
* Timeout value to give up reception from the target in case of no answer.
|
||||||
|
* Default value for this property is 52 ms).
|
||||||
|
*/
|
||||||
|
NP_TIMEOUT_COM,
|
||||||
|
/** Let the PN53X chip handle the CRC bytes. This means that the chip appends
|
||||||
* the CRC bytes to the frames that are transmitted. It will parse the last
|
* the CRC bytes to the frames that are transmitted. It will parse the last
|
||||||
* bytes from received frames as incoming CRC bytes. They will be verified
|
* bytes from received frames as incoming CRC bytes. They will be verified
|
||||||
* against the used modulation and protocol. If an frame is expected with
|
* against the used modulation and protocol. If an frame is expected with
|
||||||
* incorrect CRC bytes this option should be disabled. Example frames where
|
* incorrect CRC bytes this option should be disabled. Example frames where
|
||||||
* this is useful are the ATQA and UID+BCC that are transmitted without CRC
|
* this is useful are the ATQA and UID+BCC that are transmitted without CRC
|
||||||
* bytes during the anti-collision phase of the ISO14443-A protocol. */
|
* bytes during the anti-collision phase of the ISO14443-A protocol. */
|
||||||
NDO_HANDLE_CRC = 0x00,
|
NP_HANDLE_CRC,
|
||||||
/** Parity bits in the network layer of ISO14443-A are by default generated and
|
/** Parity bits in the network layer of ISO14443-A are by default generated and
|
||||||
* validated in the PN53X chip. This is a very convenient feature. On certain
|
* validated in the PN53X chip. This is a very convenient feature. On certain
|
||||||
* times though it is useful to get full control of the transmitted data. The
|
* times though it is useful to get full control of the transmitted data. The
|
||||||
|
@ -113,31 +81,31 @@ typedef enum {
|
||||||
* parity bits. For interoperability it is required to be completely
|
* parity bits. For interoperability it is required to be completely
|
||||||
* compatible, including the arbitrary parity bits. When this option is
|
* compatible, including the arbitrary parity bits. When this option is
|
||||||
* disabled, the functions to communicating bits should be used. */
|
* disabled, the functions to communicating bits should be used. */
|
||||||
NDO_HANDLE_PARITY = 0x01,
|
NP_HANDLE_PARITY,
|
||||||
/** This option can be used to enable or disable the electronic field of the
|
/** This option can be used to enable or disable the electronic field of the
|
||||||
* NFC device. */
|
* NFC device. */
|
||||||
NDO_ACTIVATE_FIELD = 0x10,
|
NP_ACTIVATE_FIELD,
|
||||||
/** The internal CRYPTO1 co-processor can be used to transmit messages
|
/** The internal CRYPTO1 co-processor can be used to transmit messages
|
||||||
* encrypted. This option is automatically activated after a successful MIFARE
|
* encrypted. This option is automatically activated after a successful MIFARE
|
||||||
* Classic authentication. */
|
* Classic authentication. */
|
||||||
NDO_ACTIVATE_CRYPTO1 = 0x11,
|
NP_ACTIVATE_CRYPTO1,
|
||||||
/** The default configuration defines that the PN53X chip will try indefinitely
|
/** The default configuration defines that the PN53X chip will try indefinitely
|
||||||
* to invite a tag in the field to respond. This could be desired when it is
|
* to invite a tag in the field to respond. This could be desired when it is
|
||||||
* certain a tag will enter the field. On the other hand, when this is
|
* certain a tag will enter the field. On the other hand, when this is
|
||||||
* uncertain, it will block the application. This option could best be compared
|
* uncertain, it will block the application. This option could best be compared
|
||||||
* to the (NON)BLOCKING option used by (socket)network programming. */
|
* to the (NON)BLOCKING option used by (socket)network programming. */
|
||||||
NDO_INFINITE_SELECT = 0x20,
|
NP_INFINITE_SELECT,
|
||||||
/** If this option is enabled, frames that carry less than 4 bits are allowed.
|
/** If this option is enabled, frames that carry less than 4 bits are allowed.
|
||||||
* According to the standards these frames should normally be handles as
|
* According to the standards these frames should normally be handles as
|
||||||
* invalid frames. */
|
* invalid frames. */
|
||||||
NDO_ACCEPT_INVALID_FRAMES = 0x30,
|
NP_ACCEPT_INVALID_FRAMES,
|
||||||
/** If the NFC device should only listen to frames, it could be useful to let
|
/** If the NFC device should only listen to frames, it could be useful to let
|
||||||
* it gather multiple frames in a sequence. They will be stored in the internal
|
* it gather multiple frames in a sequence. They will be stored in the internal
|
||||||
* FIFO of the PN53X chip. This could be retrieved by using the receive data
|
* FIFO of the PN53X chip. This could be retrieved by using the receive data
|
||||||
* functions. Note that if the chip runs out of bytes (FIFO = 64 bytes long),
|
* functions. Note that if the chip runs out of bytes (FIFO = 64 bytes long),
|
||||||
* it will overwrite the first received frames, so quick retrieving of the
|
* it will overwrite the first received frames, so quick retrieving of the
|
||||||
* received data is desirable. */
|
* received data is desirable. */
|
||||||
NDO_ACCEPT_MULTIPLE_FRAMES = 0x31,
|
NP_ACCEPT_MULTIPLE_FRAMES,
|
||||||
/** This option can be used to enable or disable the auto-switching mode to
|
/** This option can be used to enable or disable the auto-switching mode to
|
||||||
* ISO14443-4 is device is compliant.
|
* ISO14443-4 is device is compliant.
|
||||||
* In initiator mode, it means that NFC chip will send RATS automatically when
|
* In initiator mode, it means that NFC chip will send RATS automatically when
|
||||||
|
@ -145,151 +113,154 @@ typedef enum {
|
||||||
* requested.
|
* requested.
|
||||||
* In target mode, with a NFC chip compiliant (ie. PN532), the chip will
|
* In target mode, with a NFC chip compiliant (ie. PN532), the chip will
|
||||||
* emulate a 14443-4 PICC using hardware capability */
|
* emulate a 14443-4 PICC using hardware capability */
|
||||||
NDO_AUTO_ISO14443_4 = 0x40,
|
NP_AUTO_ISO14443_4,
|
||||||
/** Use automatic frames encapsulation and chaining. */
|
/** Use automatic frames encapsulation and chaining. */
|
||||||
NDO_EASY_FRAMING = 0x41,
|
NP_EASY_FRAMING,
|
||||||
/** Force the chip to switch in ISO14443-A */
|
/** Force the chip to switch in ISO14443-A */
|
||||||
NDO_FORCE_ISO14443_A = 0x42,
|
NP_FORCE_ISO14443_A,
|
||||||
/** Force the chip to switch in ISO14443-B */
|
/** Force the chip to switch in ISO14443-B */
|
||||||
NDO_FORCE_ISO14443_B = 0x43,
|
NP_FORCE_ISO14443_B,
|
||||||
/** Force the chip to run at 106 kbps */
|
/** Force the chip to run at 106 kbps */
|
||||||
NDO_FORCE_SPEED_106 = 0x50,
|
NP_FORCE_SPEED_106,
|
||||||
} nfc_device_option_t;
|
} nfc_property;
|
||||||
|
|
||||||
|
// Compiler directive, set struct alignment to 1 uint8_t for compatibility
|
||||||
|
# pragma pack(1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum nfc_dep_mode_t
|
* @enum nfc_dep_mode
|
||||||
* @brief NFC D.E.P. (Data Exchange Protocol) active/passive mode
|
* @brief NFC D.E.P. (Data Exchange Protocol) active/passive mode
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NDM_UNDEFINED = 0,
|
NDM_UNDEFINED = 0,
|
||||||
NDM_PASSIVE,
|
NDM_PASSIVE,
|
||||||
NDM_ACTIVE,
|
NDM_ACTIVE,
|
||||||
} nfc_dep_mode_t;
|
} nfc_dep_mode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct nfc_dep_info_t
|
* @struct nfc_dep_info
|
||||||
* @brief NFC target information in D.E.P. (Data Exchange Protocol) see ISO/IEC 18092 (NFCIP-1)
|
* @brief NFC target information in D.E.P. (Data Exchange Protocol) see ISO/IEC 18092 (NFCIP-1)
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** NFCID3 */
|
/** NFCID3 */
|
||||||
byte_t abtNFCID3[10];
|
uint8_t abtNFCID3[10];
|
||||||
/** DID */
|
/** DID */
|
||||||
byte_t btDID;
|
uint8_t btDID;
|
||||||
/** Supported send-bit rate */
|
/** Supported send-bit rate */
|
||||||
byte_t btBS;
|
uint8_t btBS;
|
||||||
/** Supported receive-bit rate */
|
/** Supported receive-bit rate */
|
||||||
byte_t btBR;
|
uint8_t btBR;
|
||||||
/** Timeout value */
|
/** Timeout value */
|
||||||
byte_t btTO;
|
uint8_t btTO;
|
||||||
/** PP Parameters */
|
/** PP Parameters */
|
||||||
byte_t btPP;
|
uint8_t btPP;
|
||||||
/** General Bytes */
|
/** General Bytes */
|
||||||
byte_t abtGB[48];
|
uint8_t abtGB[48];
|
||||||
size_t szGB;
|
size_t szGB;
|
||||||
/** DEP mode */
|
/** DEP mode */
|
||||||
nfc_dep_mode_t ndm;
|
nfc_dep_mode ndm;
|
||||||
} nfc_dep_info_t;
|
} nfc_dep_info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct nfc_iso14443a_info_t
|
* @struct nfc_iso14443a_info
|
||||||
* @brief NFC ISO14443A tag (MIFARE) information
|
* @brief NFC ISO14443A tag (MIFARE) information
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
byte_t abtAtqa[2];
|
uint8_t abtAtqa[2];
|
||||||
byte_t btSak;
|
uint8_t btSak;
|
||||||
size_t szUidLen;
|
size_t szUidLen;
|
||||||
byte_t abtUid[10];
|
uint8_t abtUid[10];
|
||||||
size_t szAtsLen;
|
size_t szAtsLen;
|
||||||
byte_t abtAts[254]; // Maximal theoretical ATS is FSD-2, FSD=256 for FSDI=8 in RATS
|
uint8_t abtAts[254]; // Maximal theoretical ATS is FSD-2, FSD=256 for FSDI=8 in RATS
|
||||||
} nfc_iso14443a_info_t;
|
} nfc_iso14443a_info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct nfc_felica_info_t
|
* @struct nfc_felica_info
|
||||||
* @brief NFC FeLiCa tag information
|
* @brief NFC FeLiCa tag information
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t szLen;
|
size_t szLen;
|
||||||
byte_t btResCode;
|
uint8_t btResCode;
|
||||||
byte_t abtId[8];
|
uint8_t abtId[8];
|
||||||
byte_t abtPad[8];
|
uint8_t abtPad[8];
|
||||||
byte_t abtSysCode[2];
|
uint8_t abtSysCode[2];
|
||||||
} nfc_felica_info_t;
|
} nfc_felica_info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct nfc_iso14443b_info_t
|
* @struct nfc_iso14443b_info
|
||||||
* @brief NFC ISO14443B tag information
|
* @brief NFC ISO14443B tag information
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** abtPupi store PUPI contained in ATQB (Answer To reQuest of type B) (see ISO14443-3) */
|
/** abtPupi store PUPI contained in ATQB (Answer To reQuest of type B) (see ISO14443-3) */
|
||||||
byte_t abtPupi[4];
|
uint8_t abtPupi[4];
|
||||||
/** abtApplicationData store Application Data contained in ATQB (see ISO14443-3) */
|
/** abtApplicationData store Application Data contained in ATQB (see ISO14443-3) */
|
||||||
byte_t abtApplicationData[4];
|
uint8_t abtApplicationData[4];
|
||||||
/** abtProtocolInfo store Protocol Info contained in ATQB (see ISO14443-3) */
|
/** abtProtocolInfo store Protocol Info contained in ATQB (see ISO14443-3) */
|
||||||
byte_t abtProtocolInfo[3];
|
uint8_t abtProtocolInfo[3];
|
||||||
/** ui8CardIdentifier store CID (Card Identifier) attributted by PCD to the PICC */
|
/** ui8CardIdentifier store CID (Card Identifier) attributted by PCD to the PICC */
|
||||||
uint8_t ui8CardIdentifier;
|
uint8_t ui8CardIdentifier;
|
||||||
} nfc_iso14443b_info_t;
|
} nfc_iso14443b_info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct nfc_iso14443bi_info_t
|
* @struct nfc_iso14443bi_info
|
||||||
* @brief NFC ISO14443B' tag information
|
* @brief NFC ISO14443B' tag information
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** DIV: 4 LSBytes of tag serial number */
|
/** DIV: 4 LSBytes of tag serial number */
|
||||||
byte_t abtDIV[4];
|
uint8_t abtDIV[4];
|
||||||
/** Software version & type of REPGEN */
|
/** Software version & type of REPGEN */
|
||||||
byte_t btVerLog;
|
uint8_t btVerLog;
|
||||||
/** Config Byte, present if long REPGEN */
|
/** Config Byte, present if long REPGEN */
|
||||||
byte_t btConfig;
|
uint8_t btConfig;
|
||||||
/** ATR, if any */
|
/** ATR, if any */
|
||||||
size_t szAtrLen;
|
size_t szAtrLen;
|
||||||
byte_t abtAtr[33];
|
uint8_t abtAtr[33];
|
||||||
} nfc_iso14443bi_info_t;
|
} nfc_iso14443bi_info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct nfc_iso14443b2sr_info_t
|
* @struct nfc_iso14443b2sr_info
|
||||||
* @brief NFC ISO14443-2B ST SRx tag information
|
* @brief NFC ISO14443-2B ST SRx tag information
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
byte_t abtUID[8];
|
uint8_t abtUID[8];
|
||||||
} nfc_iso14443b2sr_info_t;
|
} nfc_iso14443b2sr_info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct nfc_iso14443b2ct_info_t
|
* @struct nfc_iso14443b2ct_info
|
||||||
* @brief NFC ISO14443-2B ASK CTx tag information
|
* @brief NFC ISO14443-2B ASK CTx tag information
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
byte_t abtUID[4];
|
uint8_t abtUID[4];
|
||||||
byte_t btProdCode;
|
uint8_t btProdCode;
|
||||||
byte_t btFabCode;
|
uint8_t btFabCode;
|
||||||
} nfc_iso14443b2ct_info_t;
|
} nfc_iso14443b2ct_info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct nfc_jewel_info_t
|
* @struct nfc_jewel_info
|
||||||
* @brief NFC Jewel tag information
|
* @brief NFC Jewel tag information
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
byte_t btSensRes[2];
|
uint8_t btSensRes[2];
|
||||||
byte_t btId[4];
|
uint8_t btId[4];
|
||||||
} nfc_jewel_info_t;
|
} nfc_jewel_info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @union nfc_target_info_t
|
* @union nfc_target_info
|
||||||
* @brief Union between all kind of tags information structures.
|
* @brief Union between all kind of tags information structures.
|
||||||
*/
|
*/
|
||||||
typedef union {
|
typedef union {
|
||||||
nfc_iso14443a_info_t nai;
|
nfc_iso14443a_info nai;
|
||||||
nfc_felica_info_t nfi;
|
nfc_felica_info nfi;
|
||||||
nfc_iso14443b_info_t nbi;
|
nfc_iso14443b_info nbi;
|
||||||
nfc_iso14443bi_info_t nii;
|
nfc_iso14443bi_info nii;
|
||||||
nfc_iso14443b2sr_info_t nsi;
|
nfc_iso14443b2sr_info nsi;
|
||||||
nfc_iso14443b2ct_info_t nci;
|
nfc_iso14443b2ct_info nci;
|
||||||
nfc_jewel_info_t nji;
|
nfc_jewel_info nji;
|
||||||
nfc_dep_info_t ndi;
|
nfc_dep_info ndi;
|
||||||
} nfc_target_info_t;
|
} nfc_target_info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum nfc_baud_rate_t
|
* @enum nfc_baud_rate
|
||||||
* @brief NFC baud rate enumeration
|
* @brief NFC baud rate enumeration
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -298,10 +269,10 @@ typedef enum {
|
||||||
NBR_212,
|
NBR_212,
|
||||||
NBR_424,
|
NBR_424,
|
||||||
NBR_847,
|
NBR_847,
|
||||||
} nfc_baud_rate_t;
|
} nfc_baud_rate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum nfc_modulation_type_t
|
* @enum nfc_modulation_type
|
||||||
* @brief NFC modulation type enumeration
|
* @brief NFC modulation type enumeration
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -313,25 +284,25 @@ typedef enum {
|
||||||
NMT_ISO14443B2CT, // ISO14443-2B ASK CTx
|
NMT_ISO14443B2CT, // ISO14443-2B ASK CTx
|
||||||
NMT_FELICA,
|
NMT_FELICA,
|
||||||
NMT_DEP,
|
NMT_DEP,
|
||||||
} nfc_modulation_type_t;
|
} nfc_modulation_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct nfc_modulation_t
|
* @struct nfc_modulation
|
||||||
* @brief NFC modulation structure
|
* @brief NFC modulation structure
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nfc_modulation_type_t nmt;
|
nfc_modulation_type nmt;
|
||||||
nfc_baud_rate_t nbr;
|
nfc_baud_rate nbr;
|
||||||
} nfc_modulation_t;
|
} nfc_modulation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct nfc_target_t
|
* @struct nfc_target
|
||||||
* @brief NFC target structure
|
* @brief NFC target structure
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nfc_target_info_t nti;
|
nfc_target_info nti;
|
||||||
nfc_modulation_t nm;
|
nfc_modulation nm;
|
||||||
} nfc_target_t;
|
} nfc_target;
|
||||||
|
|
||||||
// Reset struct alignment to default
|
// Reset struct alignment to default
|
||||||
# pragma pack()
|
# pragma pack()
|
||||||
|
|
|
@ -62,91 +62,71 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
# endif // __cplusplus
|
# endif // __cplusplus
|
||||||
|
|
||||||
|
/* Library initialization/deinitialization */
|
||||||
|
NFC_EXPORT void nfc_init(nfc_context *context);
|
||||||
|
NFC_EXPORT void nfc_exit(nfc_context *context);
|
||||||
|
|
||||||
/* NFC Device/Hardware manipulation */
|
/* NFC Device/Hardware manipulation */
|
||||||
NFC_EXPORT nfc_device_t *nfc_connect (nfc_device_desc_t * pndd);
|
NFC_EXPORT bool nfc_get_default_device (nfc_connstring *connstring);
|
||||||
NFC_EXPORT void nfc_disconnect (nfc_device_t * pnd);
|
NFC_EXPORT nfc_device *nfc_open (nfc_context *context, const nfc_connstring connstring);
|
||||||
NFC_EXPORT bool nfc_abort_command (nfc_device_t * pnd);
|
NFC_EXPORT void nfc_close (nfc_device *pnd);
|
||||||
NFC_EXPORT void nfc_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
|
NFC_EXPORT int nfc_abort_command (nfc_device *pnd);
|
||||||
NFC_EXPORT bool nfc_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
|
NFC_EXPORT size_t nfc_list_devices (nfc_context *context, nfc_connstring connstrings[], size_t connstrings_len);
|
||||||
NFC_EXPORT bool nfc_idle (nfc_device_t * pnd);
|
NFC_EXPORT int nfc_idle (nfc_device *pnd);
|
||||||
|
|
||||||
/* NFC initiator: act as "reader" */
|
/* NFC initiator: act as "reader" */
|
||||||
NFC_EXPORT bool nfc_initiator_init (nfc_device_t * pnd);
|
NFC_EXPORT int nfc_initiator_init (nfc_device *pnd);
|
||||||
NFC_EXPORT bool nfc_initiator_select_passive_target (nfc_device_t * pnd, const nfc_modulation_t nm, const byte_t * pbtInitData, const size_t szInitData, nfc_target_t * pnt);
|
NFC_EXPORT int nfc_initiator_select_passive_target (nfc_device *pnd, const nfc_modulation nm, const uint8_t *pbtInitData, const size_t szInitData, nfc_target *pnt);
|
||||||
NFC_EXPORT bool nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t nm, nfc_target_t ant[], const size_t szTargets, size_t * pszTargetFound);
|
NFC_EXPORT int nfc_initiator_list_passive_targets (nfc_device *pnd, const nfc_modulation nm, nfc_target ant[], const size_t szTargets);
|
||||||
NFC_EXPORT bool nfc_initiator_poll_target (nfc_device_t * pnd, const nfc_modulation_t * pnmTargetTypes, const size_t szTargetTypes, const uint8_t uiPollNr, const uint8_t uiPeriod, nfc_target_t * pnt);
|
NFC_EXPORT int nfc_initiator_poll_target (nfc_device *pnd, const nfc_modulation *pnmTargetTypes, const size_t szTargetTypes, const uint8_t uiPollNr, const uint8_t uiPeriod, nfc_target *pnt);
|
||||||
NFC_EXPORT bool nfc_initiator_select_dep_target (nfc_device_t * pnd, const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr, const nfc_dep_info_t * pndiInitiator, nfc_target_t * pnt);
|
NFC_EXPORT int nfc_initiator_select_dep_target (nfc_device *pnd, const nfc_dep_mode ndm, const nfc_baud_rate nbr, const nfc_dep_info *pndiInitiator, nfc_target *pnt, const int timeout);
|
||||||
NFC_EXPORT bool nfc_initiator_deselect_target (nfc_device_t * pnd);
|
NFC_EXPORT int nfc_initiator_poll_dep_target (nfc_device *pnd, const nfc_dep_mode ndm, const nfc_baud_rate nbr, const nfc_dep_info *pndiInitiator, nfc_target *pnt, const int timeout);
|
||||||
NFC_EXPORT bool nfc_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
|
NFC_EXPORT int nfc_initiator_deselect_target (nfc_device *pnd);
|
||||||
NFC_EXPORT bool nfc_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
|
NFC_EXPORT int nfc_initiator_transceive_bytes (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, size_t *pszRx, int timeout);
|
||||||
NFC_EXPORT bool nfc_initiator_transceive_bytes_timed (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx, uint32_t * cycles);
|
NFC_EXPORT int nfc_initiator_transceive_bits (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar);
|
||||||
NFC_EXPORT bool nfc_initiator_transceive_bits_timed (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar, uint32_t * cycles);
|
NFC_EXPORT int nfc_initiator_transceive_bytes_timed (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, uint32_t *cycles);
|
||||||
|
NFC_EXPORT int nfc_initiator_transceive_bits_timed (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar, uint32_t *cycles);
|
||||||
|
|
||||||
/* NFC target: act as tag (i.e. MIFARE Classic) or NFC target device. */
|
/* NFC target: act as tag (i.e. MIFARE Classic) or NFC target device. */
|
||||||
NFC_EXPORT bool nfc_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx);
|
NFC_EXPORT int nfc_target_init (nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRx, int timeout);
|
||||||
NFC_EXPORT bool nfc_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, struct timeval *timout);
|
NFC_EXPORT int nfc_target_send_bytes (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int timeout);
|
||||||
NFC_EXPORT bool nfc_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx, struct timeval *timout);
|
NFC_EXPORT int nfc_target_receive_bytes (nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, int timeout);
|
||||||
NFC_EXPORT bool nfc_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar);
|
NFC_EXPORT int nfc_target_send_bits (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar);
|
||||||
NFC_EXPORT bool nfc_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
|
NFC_EXPORT int nfc_target_receive_bits (nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar);
|
||||||
|
|
||||||
/* Error reporting */
|
/* Error reporting */
|
||||||
NFC_EXPORT const char *nfc_strerror (const nfc_device_t * pnd);
|
NFC_EXPORT const char *nfc_strerror (const nfc_device *pnd);
|
||||||
NFC_EXPORT int nfc_strerror_r (const nfc_device_t * pnd, char *pcStrErrBuf, size_t szBufLen);
|
NFC_EXPORT int nfc_strerror_r (const nfc_device *pnd, char *buf, size_t buflen);
|
||||||
NFC_EXPORT void nfc_perror (const nfc_device_t * pnd, const char *pcString);
|
NFC_EXPORT void nfc_perror (const nfc_device *pnd, const char *s);
|
||||||
|
NFC_EXPORT int nfc_device_get_last_error (const nfc_device *pnd);
|
||||||
|
|
||||||
/* Special data accessors */
|
/* Special data accessors */
|
||||||
NFC_EXPORT const char *nfc_device_name (nfc_device_t * pnd);
|
NFC_EXPORT const char *nfc_device_get_name (nfc_device *pnd);
|
||||||
|
NFC_EXPORT const char *nfc_device_get_connstring (nfc_device *pnd);
|
||||||
|
|
||||||
|
/* Properties accessors */
|
||||||
|
NFC_EXPORT int nfc_device_set_property_int (nfc_device *pnd, const nfc_property property, const int value);
|
||||||
|
NFC_EXPORT int nfc_device_set_property_bool (nfc_device *pnd, const nfc_property property, const bool bEnable);
|
||||||
|
|
||||||
/* Misc. functions */
|
/* Misc. functions */
|
||||||
NFC_EXPORT void iso14443a_crc (byte_t * pbtData, size_t szLen, byte_t * pbtCrc);
|
NFC_EXPORT void iso14443a_crc (uint8_t *pbtData, size_t szLen, uint8_t *pbtCrc);
|
||||||
NFC_EXPORT void iso14443a_crc_append (byte_t * pbtData, size_t szLen);
|
NFC_EXPORT void iso14443a_crc_append (uint8_t *pbtData, size_t szLen);
|
||||||
NFC_EXPORT byte_t * iso14443a_locate_historical_bytes (byte_t * pbtAts, size_t szAts, size_t * pszTk);
|
NFC_EXPORT uint8_t *iso14443a_locate_historical_bytes (uint8_t *pbtAts, size_t szAts, size_t *pszTk);
|
||||||
NFC_EXPORT const char *nfc_version (void);
|
NFC_EXPORT const char *nfc_version (void);
|
||||||
|
|
||||||
/* PN53x specific errors */
|
/* Error codes */
|
||||||
// TODO: Be not PN53x-specific here
|
#define NFC_SUCCESS 0 // No error
|
||||||
#define ETIMEOUT 0x01
|
#define NFC_EIO -1 // Input / output error, device will not be usable anymore
|
||||||
#define ECRC 0x02
|
#define NFC_EINVARG -2 // Invalid argument(s)
|
||||||
#define EPARITY 0x03
|
#define NFC_EDEVNOTSUPP -3 // Operation not supported by device
|
||||||
#define EBITCOUNT 0x04
|
#define NFC_ENOTSUCHDEV -4 // No such device
|
||||||
#define EFRAMING 0x05
|
#define NFC_EOVFLOW -5 // Buffer overflow
|
||||||
#define EBITCOLL 0x06
|
#define NFC_ETIMEOUT -6 // Operation timed out
|
||||||
#define ESMALLBUF 0x07
|
#define NFC_EOPABORTED -7 // Operation aborted (by user)
|
||||||
#define EBUFOVF 0x09
|
#define NFC_ENOTIMPL -8 // Not (yet) implemented
|
||||||
#define ERFTIMEOUT 0x0a
|
#define NFC_ETGRELEASED -10 // Target released
|
||||||
#define ERFPROTO 0x0b
|
#define NFC_ERFTRANS -20 // Error while RF transmission
|
||||||
#define EOVHEAT 0x0d
|
#define NFC_ECHIP -90 // Device's internal chip error
|
||||||
#define EINBUFOVF 0x0e
|
|
||||||
#define EINVPARAM 0x10
|
|
||||||
#define EDEPUNKCMD 0x12
|
|
||||||
#define EINVRXFRAM 0x13
|
|
||||||
#define EMFAUTH 0x14
|
|
||||||
#define ENSECNOTSUPP 0x18 // PN533 only
|
|
||||||
#define EBCC 0x23
|
|
||||||
#define EDEPINVSTATE 0x25
|
|
||||||
#define EOPNOTALL 0x26
|
|
||||||
#define ECMD 0x27
|
|
||||||
#define ETGREL 0x29
|
|
||||||
#define ECID 0x2a
|
|
||||||
#define ECDISCARDED 0x2b
|
|
||||||
#define ENFCID3 0x2c
|
|
||||||
#define EOVCURRENT 0x2d
|
|
||||||
#define ENAD 0x2e
|
|
||||||
|
|
||||||
/* PN53x framing-level errors */
|
|
||||||
#define EFRAACKMISMATCH 0x0100 /* Unexpected data */
|
|
||||||
#define EFRAISERRFRAME 0x0101 /* Error frame */
|
|
||||||
|
|
||||||
/* Communication-level errors */
|
|
||||||
#define ECOMIO 0x1000 /* Input/output error */
|
|
||||||
#define ECOMTIMEOUT 0x1001 /* Operation timeout */
|
|
||||||
|
|
||||||
/* Software level errors */
|
|
||||||
#define ETGUIDNOTSUP 0xFF00 /* Target UID not supported */
|
|
||||||
#define EOPABORT 0xFF01 /* Operation aborted */
|
|
||||||
#define EINVALARG 0xFF02 /* Invalid argument */
|
|
||||||
#define EDEVNOTSUP 0xFF03 /* Not supported by device */
|
|
||||||
#define ENOTIMPL 0xFF04 /* Not (yet) implemented in libnfc */
|
|
||||||
|
|
||||||
# ifdef __cplusplus
|
# ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ libnfc_la_SOURCES = \
|
||||||
nfc-emulation.c \
|
nfc-emulation.c \
|
||||||
nfc-internal.c
|
nfc-internal.c
|
||||||
|
|
||||||
libnfc_la_LDFLAGS = -no-undefined -version-info 2:0:0
|
libnfc_la_LDFLAGS = -no-undefined -version-info 2:0:0 -export-symbols-regex '^nfc_|^iso14443a_|pn53x_transceive|pn53x_SAMConfiguration'
|
||||||
libnfc_la_CFLAGS = @DRIVERS_CFLAGS@
|
libnfc_la_CFLAGS = @DRIVERS_CFLAGS@
|
||||||
libnfc_la_LIBADD = \
|
libnfc_la_LIBADD = \
|
||||||
$(top_builddir)/libnfc/chips/libnfcchips.la \
|
$(top_builddir)/libnfc/chips/libnfcchips.la \
|
||||||
|
@ -35,11 +35,11 @@ if LIBUSB_ENABLED
|
||||||
libnfc_la_LIBADD += @libusb_LIBS@
|
libnfc_la_LIBADD += @libusb_LIBS@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if HAS_LOG4C
|
if WITH_DEBUG
|
||||||
libnfc_la_CFLAGS += @log4c_CFLAGS@
|
libnfc_la_SOURCES += log-printf.c
|
||||||
libnfc_la_LIBADD += @log4c_LIBS@
|
|
||||||
|
|
||||||
libnfc_la_SOURCES += log.c
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
EXTRA_DIST = CMakeLists.txt
|
EXTRA_DIST = \
|
||||||
|
CMakeLists.txt \
|
||||||
|
log-printf.c
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,3 @@ libnfcbuses_la_CFLAGS = -I$(top_srcdir)/libnfc
|
||||||
|
|
||||||
EXTRA_DIST = uart_posix.c uart_win32.c
|
EXTRA_DIST = uart_posix.c uart_win32.c
|
||||||
|
|
||||||
if HAS_LOG4C
|
|
||||||
libnfcbuses_la_CFLAGS += @log4c_CFLAGS@
|
|
||||||
libnfcbuses_la_LIBADD = @log4c_LIBS@
|
|
||||||
endif
|
|
||||||
|
|
|
@ -49,8 +49,8 @@ void uart_flush_input (const serial_port sp);
|
||||||
void uart_set_speed (serial_port sp, const uint32_t uiPortSpeed);
|
void uart_set_speed (serial_port sp, const uint32_t uiPortSpeed);
|
||||||
uint32_t uart_get_speed (const serial_port sp);
|
uint32_t uart_get_speed (const serial_port sp);
|
||||||
|
|
||||||
int uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx, void * abort_p, struct timeval *timeout);
|
int uart_receive (serial_port sp, uint8_t *pbtRx, const size_t szRx, void *abort_p, int timeout);
|
||||||
int uart_send (serial_port sp, const byte_t * pbtTx, const size_t szTx, struct timeval *timeout);
|
int uart_send (serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout);
|
||||||
|
|
||||||
char **uart_list_ports (void);
|
char **uart_list_ports (void);
|
||||||
|
|
||||||
|
|
|
@ -61,18 +61,20 @@ char *serial_ports_device_radix[] = { "ttyUSB", "ttyS", NULL };
|
||||||
// Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct
|
// Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct
|
||||||
# define CCLAIMED 0x80000000
|
# define CCLAIMED 0x80000000
|
||||||
|
|
||||||
typedef struct {
|
struct serial_port_unix{
|
||||||
int fd; // Serial port file descriptor
|
int fd; // Serial port file descriptor
|
||||||
struct termios termios_backup; // Terminal info before using the port
|
struct termios termios_backup; // Terminal info before using the port
|
||||||
struct termios termios_new; // Terminal info during the transaction
|
struct termios termios_new; // Terminal info during the transaction
|
||||||
} serial_port_unix;
|
};
|
||||||
|
|
||||||
|
#define UART_DATA( X ) ((struct serial_port_unix *) X)
|
||||||
|
|
||||||
void uart_close_ext (const serial_port sp, const bool restore_termios);
|
void uart_close_ext (const serial_port sp, const bool restore_termios);
|
||||||
|
|
||||||
serial_port
|
serial_port
|
||||||
uart_open (const char *pcPortName)
|
uart_open (const char *pcPortName)
|
||||||
{
|
{
|
||||||
serial_port_unix *sp = malloc (sizeof (serial_port_unix));
|
struct serial_port_unix *sp = malloc (sizeof (struct serial_port_unix));
|
||||||
|
|
||||||
if (sp == 0)
|
if (sp == 0)
|
||||||
return INVALID_SERIAL_PORT;
|
return INVALID_SERIAL_PORT;
|
||||||
|
@ -114,12 +116,12 @@ void
|
||||||
uart_flush_input (serial_port sp)
|
uart_flush_input (serial_port sp)
|
||||||
{
|
{
|
||||||
// This line seems to produce absolutely no effect on my system (GNU/Linux 2.6.35)
|
// This line seems to produce absolutely no effect on my system (GNU/Linux 2.6.35)
|
||||||
tcflush (((serial_port_unix *) sp)->fd, TCIFLUSH);
|
tcflush (UART_DATA(sp)->fd, TCIFLUSH);
|
||||||
// So, I wrote this byte-eater
|
// So, I wrote this byte-eater
|
||||||
// Retrieve the count of the incoming bytes
|
// Retrieve the count of the incoming bytes
|
||||||
int available_bytes_count = 0;
|
int available_bytes_count = 0;
|
||||||
int res;
|
int res;
|
||||||
res = ioctl (((serial_port_unix *) sp)->fd, FIONREAD, &available_bytes_count);
|
res = ioctl (UART_DATA(sp)->fd, FIONREAD, &available_bytes_count);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +130,7 @@ uart_flush_input (serial_port sp)
|
||||||
}
|
}
|
||||||
char* rx = malloc (available_bytes_count);
|
char* rx = malloc (available_bytes_count);
|
||||||
// There is something available, read the data
|
// There is something available, read the data
|
||||||
res = read (((serial_port_unix *) sp)->fd, rx, available_bytes_count);
|
res = read (UART_DATA(sp)->fd, rx, available_bytes_count);
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%d bytes have eatten.", available_bytes_count);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%d bytes have eatten.", available_bytes_count);
|
||||||
free (rx);
|
free (rx);
|
||||||
}
|
}
|
||||||
|
@ -137,8 +139,7 @@ void
|
||||||
uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
|
uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
|
||||||
{
|
{
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
||||||
serial_port_unix *spu = (serial_port_unix *) sp;
|
|
||||||
|
|
||||||
// Portability note: on some systems, B9600 != 9600 so we have to do
|
// Portability note: on some systems, B9600 != 9600 so we have to do
|
||||||
// uint32_t <=> speed_t associations by hand.
|
// uint32_t <=> speed_t associations by hand.
|
||||||
speed_t stPortSpeed = B9600;
|
speed_t stPortSpeed = B9600;
|
||||||
|
@ -179,9 +180,9 @@ uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set port speed (Input and Output)
|
// Set port speed (Input and Output)
|
||||||
cfsetispeed (&(spu->termios_new), stPortSpeed);
|
cfsetispeed (&(UART_DATA(sp)->termios_new), stPortSpeed);
|
||||||
cfsetospeed (&(spu->termios_new), stPortSpeed);
|
cfsetospeed (&(UART_DATA(sp)->termios_new), stPortSpeed);
|
||||||
if (tcsetattr (spu->fd, TCSADRAIN, &(spu->termios_new)) == -1) {
|
if (tcsetattr (UART_DATA(sp)->fd, TCSADRAIN, &(UART_DATA(sp)->termios_new)) == -1) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to apply new speed settings.");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to apply new speed settings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,8 +191,7 @@ uint32_t
|
||||||
uart_get_speed (serial_port sp)
|
uart_get_speed (serial_port sp)
|
||||||
{
|
{
|
||||||
uint32_t uiPortSpeed = 0;
|
uint32_t uiPortSpeed = 0;
|
||||||
const serial_port_unix *spu = (serial_port_unix *) sp;
|
switch (cfgetispeed (&UART_DATA(sp)->termios_new)) {
|
||||||
switch (cfgetispeed (&spu->termios_new)) {
|
|
||||||
case B9600:
|
case B9600:
|
||||||
uiPortSpeed = 9600;
|
uiPortSpeed = 9600;
|
||||||
break;
|
break;
|
||||||
|
@ -229,10 +229,10 @@ uart_get_speed (serial_port sp)
|
||||||
void
|
void
|
||||||
uart_close_ext (const serial_port sp, const bool restore_termios)
|
uart_close_ext (const serial_port sp, const bool restore_termios)
|
||||||
{
|
{
|
||||||
if (((serial_port_unix *) sp)->fd >= 0) {
|
if (UART_DATA(sp)->fd >= 0) {
|
||||||
if (restore_termios)
|
if (restore_termios)
|
||||||
tcsetattr (((serial_port_unix *) sp)->fd, TCSANOW, &((serial_port_unix *) sp)->termios_backup);
|
tcsetattr (UART_DATA(sp)->fd, TCSANOW, &UART_DATA(sp)->termios_backup);
|
||||||
close (((serial_port_unix *) sp)->fd);
|
close (UART_DATA(sp)->fd);
|
||||||
}
|
}
|
||||||
free (sp);
|
free (sp);
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ uart_close (const serial_port sp)
|
||||||
* @return 0 on success, otherwise driver error code
|
* @return 0 on success, otherwise driver error code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx, void * abort_p, struct timeval *timeout)
|
uart_receive (serial_port sp, uint8_t *pbtRx, const size_t szRx, void *abort_p, int timeout)
|
||||||
{
|
{
|
||||||
int iAbortFd = abort_p ? *((int*)abort_p) : 0;
|
int iAbortFd = abort_p ? *((int*)abort_p) : 0;
|
||||||
int received_bytes_count = 0;
|
int received_bytes_count = 0;
|
||||||
|
@ -261,23 +261,19 @@ uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx, void * abort_p,
|
||||||
select:
|
select:
|
||||||
// Reset file descriptor
|
// Reset file descriptor
|
||||||
FD_ZERO (&rfds);
|
FD_ZERO (&rfds);
|
||||||
FD_SET (((serial_port_unix *) sp)->fd, &rfds);
|
FD_SET (UART_DATA(sp)->fd, &rfds);
|
||||||
|
|
||||||
if (iAbortFd) {
|
if (iAbortFd) {
|
||||||
FD_SET (iAbortFd, &rfds);
|
FD_SET (iAbortFd, &rfds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
struct timeval timeout_tv;
|
||||||
* Some implementations (e.g. Linux) of select(2) will update *timeout.
|
if (timeout > 0) {
|
||||||
* Make a copy so that it will be updated on these systems,
|
timeout_tv.tv_sec = (timeout / 1000);
|
||||||
*/
|
timeout_tv.tv_usec = ((timeout % 1000) * 1000);
|
||||||
struct timeval fixed_timeout;
|
|
||||||
if (timeout) {
|
|
||||||
fixed_timeout = *timeout;
|
|
||||||
timeout = &fixed_timeout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res = select (MAX(((serial_port_unix *) sp)->fd, iAbortFd) + 1, &rfds, NULL, NULL, timeout);
|
res = select (MAX(UART_DATA(sp)->fd, iAbortFd) + 1, &rfds, NULL, NULL, timeout ? &timeout_tv : NULL);
|
||||||
|
|
||||||
if ((res < 0) && (EINTR == errno)) {
|
if ((res < 0) && (EINTR == errno)) {
|
||||||
// The system call was interupted by a signal and a signal handler was
|
// The system call was interupted by a signal and a signal handler was
|
||||||
|
@ -287,38 +283,38 @@ select:
|
||||||
|
|
||||||
// Read error
|
// Read error
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%s", "RX error.");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Error: %s", strerror(errno));
|
||||||
return ECOMIO;
|
return NFC_EIO;
|
||||||
}
|
}
|
||||||
// Read time-out
|
// Read time-out
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Timeout!");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Timeout!");
|
||||||
return ECOMTIMEOUT;
|
return NFC_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET (iAbortFd, &rfds)) {
|
if (FD_ISSET (iAbortFd, &rfds)) {
|
||||||
// Abort requested
|
// Abort requested
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Abort!");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Abort!");
|
||||||
close (iAbortFd);
|
close (iAbortFd);
|
||||||
return EOPABORT;
|
return NFC_EOPABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the count of the incoming bytes
|
// Retrieve the count of the incoming bytes
|
||||||
res = ioctl (((serial_port_unix *) sp)->fd, FIONREAD, &available_bytes_count);
|
res = ioctl (UART_DATA(sp)->fd, FIONREAD, &available_bytes_count);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
return ECOMIO;
|
return NFC_EIO;
|
||||||
}
|
}
|
||||||
// There is something available, read the data
|
// There is something available, read the data
|
||||||
res = read (((serial_port_unix *) sp)->fd, pbtRx + received_bytes_count, MIN(available_bytes_count, (expected_bytes_count - received_bytes_count)));
|
res = read (UART_DATA(sp)->fd, pbtRx + received_bytes_count, MIN(available_bytes_count, (expected_bytes_count - received_bytes_count)));
|
||||||
// Stop if the OS has some troubles reading the data
|
// Stop if the OS has some troubles reading the data
|
||||||
if (res <= 0) {
|
if (res <= 0) {
|
||||||
return ECOMIO;
|
return NFC_EIO;
|
||||||
}
|
}
|
||||||
received_bytes_count += res;
|
received_bytes_count += res;
|
||||||
|
|
||||||
} while (expected_bytes_count > received_bytes_count);
|
} while (expected_bytes_count > received_bytes_count);
|
||||||
LOG_HEX ("RX", pbtRx, szRx);
|
LOG_HEX ("RX", pbtRx, szRx);
|
||||||
return 0;
|
return NFC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -327,14 +323,14 @@ select:
|
||||||
* @return 0 on success, otherwise a driver error is returned
|
* @return 0 on success, otherwise a driver error is returned
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
uart_send (serial_port sp, const byte_t * pbtTx, const size_t szTx, struct timeval *timeout)
|
uart_send (serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout)
|
||||||
{
|
{
|
||||||
(void) timeout;
|
(void) timeout;
|
||||||
LOG_HEX ("TX", pbtTx, szTx);
|
LOG_HEX ("TX", pbtTx, szTx);
|
||||||
if ((int) szTx == write (((serial_port_unix *) sp)->fd, pbtTx, szTx))
|
if ((int) szTx == write (UART_DATA(sp)->fd, pbtTx, szTx))
|
||||||
return 0;
|
return NFC_SUCCESS;
|
||||||
else
|
else
|
||||||
return ECOMIO;
|
return NFC_EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
char **
|
char **
|
||||||
|
|
|
@ -31,17 +31,17 @@
|
||||||
#include "contrib/windows.h"
|
#include "contrib/windows.h"
|
||||||
#define delay_ms( X ) Sleep( X )
|
#define delay_ms( X ) Sleep( X )
|
||||||
|
|
||||||
typedef struct {
|
struct serial_port_windows {
|
||||||
HANDLE hPort; // Serial port handle
|
HANDLE hPort; // Serial port handle
|
||||||
DCB dcb; // Device control settings
|
DCB dcb; // Device control settings
|
||||||
COMMTIMEOUTS ct; // Serial port time-out configuration
|
COMMTIMEOUTS ct; // Serial port time-out configuration
|
||||||
} serial_port_windows;
|
};
|
||||||
|
|
||||||
serial_port
|
serial_port
|
||||||
uart_open (const char *pcPortName)
|
uart_open (const char *pcPortName)
|
||||||
{
|
{
|
||||||
char acPortName[255];
|
char acPortName[255];
|
||||||
serial_port_windows *sp = malloc (sizeof (serial_port_windows));
|
struct serial_port_windows *sp = malloc (sizeof (struct serial_port_windows));
|
||||||
|
|
||||||
// Copy the input "com?" to "\\.\COM?" format
|
// Copy the input "com?" to "\\.\COM?" format
|
||||||
sprintf (acPortName, "\\\\.\\%s", pcPortName);
|
sprintf (acPortName, "\\\\.\\%s", pcPortName);
|
||||||
|
@ -85,8 +85,8 @@ uart_open (const char *pcPortName)
|
||||||
void
|
void
|
||||||
uart_close (const serial_port sp)
|
uart_close (const serial_port sp)
|
||||||
{
|
{
|
||||||
if (((serial_port_windows *) sp)->hPort != INVALID_HANDLE_VALUE) {
|
if (((struct serial_port_windows *) sp)->hPort != INVALID_HANDLE_VALUE) {
|
||||||
CloseHandle (((serial_port_windows *) sp)->hPort);
|
CloseHandle (((struct serial_port_windows *) sp)->hPort);
|
||||||
}
|
}
|
||||||
free (sp);
|
free (sp);
|
||||||
}
|
}
|
||||||
|
@ -94,13 +94,13 @@ uart_close (const serial_port sp)
|
||||||
void
|
void
|
||||||
uart_flush_input (const serial_port sp)
|
uart_flush_input (const serial_port sp)
|
||||||
{
|
{
|
||||||
PurgeComm(((serial_port_windows *) sp)->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
|
PurgeComm(((struct serial_port_windows *) sp)->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
|
uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
|
||||||
{
|
{
|
||||||
serial_port_windows *spw;
|
struct serial_port_windows *spw;
|
||||||
|
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
||||||
// Set port speed (Input and Output)
|
// Set port speed (Input and Output)
|
||||||
|
@ -117,7 +117,7 @@ uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
|
||||||
log_put (LOG_CATEGORY, NFC_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_CATEGORY, NFC_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);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
spw = (serial_port_windows *) sp;
|
spw = (struct serial_port_windows *) sp;
|
||||||
|
|
||||||
// Set baud rate
|
// Set baud rate
|
||||||
spw->dcb.BaudRate = uiPortSpeed;
|
spw->dcb.BaudRate = uiPortSpeed;
|
||||||
|
@ -131,7 +131,7 @@ uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
|
||||||
uint32_t
|
uint32_t
|
||||||
uart_get_speed (const serial_port sp)
|
uart_get_speed (const serial_port sp)
|
||||||
{
|
{
|
||||||
const serial_port_windows *spw = (serial_port_windows *) sp;
|
const struct serial_port_windows *spw = (struct serial_port_windows *) sp;
|
||||||
if (!GetCommState (spw->hPort, (serial_port) & spw->dcb))
|
if (!GetCommState (spw->hPort, (serial_port) & spw->dcb))
|
||||||
return spw->dcb.BaudRate;
|
return spw->dcb.BaudRate;
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ uart_get_speed (const serial_port sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx, void * abort_p, struct timeval *timeout)
|
uart_receive (serial_port sp, uint8_t * pbtRx, const size_t szRx, void * abort_p, int timeout)
|
||||||
{
|
{
|
||||||
DWORD dwBytesToGet = (DWORD)szRx;
|
DWORD dwBytesToGet = (DWORD)szRx;
|
||||||
DWORD dwBytesReceived = 0;
|
DWORD dwBytesReceived = 0;
|
||||||
|
@ -147,7 +147,7 @@ uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx, void * abort_p,
|
||||||
BOOL res;
|
BOOL res;
|
||||||
|
|
||||||
// XXX Put this part into uart_win32_timeouts () ?
|
// XXX Put this part into uart_win32_timeouts () ?
|
||||||
DWORD timeout_ms = timeout ? ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000)) : 0;
|
DWORD timeout_ms = timeout;
|
||||||
COMMTIMEOUTS timeouts;
|
COMMTIMEOUTS timeouts;
|
||||||
timeouts.ReadIntervalTimeout = 0;
|
timeouts.ReadIntervalTimeout = 0;
|
||||||
timeouts.ReadTotalTimeoutMultiplier = 0;
|
timeouts.ReadTotalTimeoutMultiplier = 0;
|
||||||
|
@ -155,7 +155,7 @@ uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx, void * abort_p,
|
||||||
timeouts.WriteTotalTimeoutMultiplier = 0;
|
timeouts.WriteTotalTimeoutMultiplier = 0;
|
||||||
timeouts.WriteTotalTimeoutConstant = timeout_ms;
|
timeouts.WriteTotalTimeoutConstant = timeout_ms;
|
||||||
|
|
||||||
if (!SetCommTimeouts (((serial_port_windows *) sp)->hPort, &timeouts)) {
|
if (!SetCommTimeouts (((struct serial_port_windows *) sp)->hPort, &timeouts)) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to apply new timeout settings.");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to apply new timeout settings.");
|
||||||
return ECOMIO;
|
return ECOMIO;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx, void * abort_p,
|
||||||
volatile bool * abort_flag_p = (volatile bool *)abort_p;
|
volatile bool * abort_flag_p = (volatile bool *)abort_p;
|
||||||
do {
|
do {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "ReadFile");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "ReadFile");
|
||||||
res = ReadFile (((serial_port_windows *) sp)->hPort, pbtRx + dwTotalBytesReceived,
|
res = ReadFile (((struct serial_port_windows *) sp)->hPort, pbtRx + dwTotalBytesReceived,
|
||||||
dwBytesToGet,
|
dwBytesToGet,
|
||||||
&dwBytesReceived, NULL);
|
&dwBytesReceived, NULL);
|
||||||
|
|
||||||
|
@ -194,24 +194,24 @@ uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx, void * abort_p,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
uart_send (serial_port sp, const byte_t * pbtTx, const size_t szTx, struct timeval *timeout)
|
uart_send (serial_port sp, const uint8_t * pbtTx, const size_t szTx, int timeout)
|
||||||
{
|
{
|
||||||
DWORD dwTxLen = 0;
|
DWORD dwTxLen = 0;
|
||||||
|
|
||||||
COMMTIMEOUTS timeouts;
|
COMMTIMEOUTS timeouts;
|
||||||
timeouts.ReadIntervalTimeout = 0;
|
timeouts.ReadIntervalTimeout = 0;
|
||||||
timeouts.ReadTotalTimeoutMultiplier = 0;
|
timeouts.ReadTotalTimeoutMultiplier = 0;
|
||||||
timeouts.ReadTotalTimeoutConstant = timeout ? ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000)) : 0;
|
timeouts.ReadTotalTimeoutConstant = timeout;
|
||||||
timeouts.WriteTotalTimeoutMultiplier = 0;
|
timeouts.WriteTotalTimeoutMultiplier = 0;
|
||||||
timeouts.WriteTotalTimeoutConstant = timeout ? ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000)) : 0;
|
timeouts.WriteTotalTimeoutConstant = timeout;
|
||||||
|
|
||||||
if (!SetCommTimeouts (((serial_port_windows *) sp)->hPort, &timeouts)) {
|
if (!SetCommTimeouts (((struct serial_port_windows *) sp)->hPort, &timeouts)) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to apply new timeout settings.");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to apply new timeout settings.");
|
||||||
return ECOMIO;
|
return ECOMIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_HEX ("TX", pbtTx, szTx);
|
LOG_HEX ("TX", pbtTx, szTx);
|
||||||
if (!WriteFile (((serial_port_windows *) sp)->hPort, pbtTx, szTx, &dwTxLen, NULL)) {
|
if (!WriteFile (((struct serial_port_windows *) sp)->hPort, pbtTx, szTx, &dwTxLen, NULL)) {
|
||||||
return ECOMIO;
|
return ECOMIO;
|
||||||
}
|
}
|
||||||
if (!dwTxLen)
|
if (!dwTxLen)
|
||||||
|
@ -238,7 +238,7 @@ BOOL is_port_available(int nPort)
|
||||||
char **
|
char **
|
||||||
uart_list_ports (void)
|
uart_list_ports (void)
|
||||||
{
|
{
|
||||||
char ** availablePorts = malloc((1 + MAX_SERIAL_PORT_WIN) * sizeof(char*));
|
char **availablePorts = malloc((1 + MAX_SERIAL_PORT_WIN) * sizeof(char*));
|
||||||
int curIndex = 0;
|
int curIndex = 0;
|
||||||
int i;
|
int i;
|
||||||
for (i = 1; i <= MAX_SERIAL_PORT_WIN; i++) {
|
for (i = 1; i <= MAX_SERIAL_PORT_WIN; i++) {
|
||||||
|
|
|
@ -7,9 +7,3 @@ noinst_LTLIBRARIES = libnfcchips.la
|
||||||
libnfcchips_la_SOURCES = pn53x.c
|
libnfcchips_la_SOURCES = pn53x.c
|
||||||
libnfcchips_la_CFLAGS = -I$(top_srcdir)/libnfc
|
libnfcchips_la_CFLAGS = -I$(top_srcdir)/libnfc
|
||||||
|
|
||||||
|
|
||||||
if HAS_LOG4C
|
|
||||||
libnfcchips_la_CFLAGS += @log4c_CFLAGS@
|
|
||||||
libnfcchips_la_LIBADD = @log4c_LIBS@
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ typedef struct {
|
||||||
uint8_t ui8Code;
|
uint8_t ui8Code;
|
||||||
uint8_t ui8CompatFlags;
|
uint8_t ui8CompatFlags;
|
||||||
#ifdef LOGGING
|
#ifdef LOGGING
|
||||||
const char * abtCommandText;
|
const char *abtCommandText;
|
||||||
#endif
|
#endif
|
||||||
} pn53x_command;
|
} pn53x_command;
|
||||||
|
|
||||||
|
@ -203,8 +203,8 @@ static const pn53x_command pn53x_commands[] = {
|
||||||
#ifdef LOGGING
|
#ifdef LOGGING
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t ui16Address;
|
uint16_t ui16Address;
|
||||||
const char * abtRegisterText;
|
const char *abtRegisterText;
|
||||||
const char * abtRegisterDescription;
|
const char *abtRegisterDescription;
|
||||||
} pn53x_register;
|
} pn53x_register;
|
||||||
|
|
||||||
# define PNREG( X, Y ) { X , #X, Y }
|
# define PNREG( X, Y ) { X , #X, Y }
|
||||||
|
@ -299,6 +299,34 @@ typedef struct {
|
||||||
#define PN53X_SFR_P7CFGB 0xFFF5
|
#define PN53X_SFR_P7CFGB 0xFFF5
|
||||||
#define PN53X_SFR_P7 0xFFF7
|
#define PN53X_SFR_P7 0xFFF7
|
||||||
|
|
||||||
|
/* PN53x specific errors */
|
||||||
|
#define ETIMEOUT 0x01
|
||||||
|
#define ECRC 0x02
|
||||||
|
#define EPARITY 0x03
|
||||||
|
#define EBITCOUNT 0x04
|
||||||
|
#define EFRAMING 0x05
|
||||||
|
#define EBITCOLL 0x06
|
||||||
|
#define ESMALLBUF 0x07
|
||||||
|
#define EBUFOVF 0x09
|
||||||
|
#define ERFTIMEOUT 0x0a
|
||||||
|
#define ERFPROTO 0x0b
|
||||||
|
#define EOVHEAT 0x0d
|
||||||
|
#define EINBUFOVF 0x0e
|
||||||
|
#define EINVPARAM 0x10
|
||||||
|
#define EDEPUNKCMD 0x12
|
||||||
|
#define EINVRXFRAM 0x13
|
||||||
|
#define EMFAUTH 0x14
|
||||||
|
#define ENSECNOTSUPP 0x18 // PN533 only
|
||||||
|
#define EBCC 0x23
|
||||||
|
#define EDEPINVSTATE 0x25
|
||||||
|
#define EOPNOTALL 0x26
|
||||||
|
#define ECMD 0x27
|
||||||
|
#define ETGREL 0x29
|
||||||
|
#define ECID 0x2a
|
||||||
|
#define ECDISCARDED 0x2b
|
||||||
|
#define ENFCID3 0x2c
|
||||||
|
#define EOVCURRENT 0x2d
|
||||||
|
#define ENAD 0x2e
|
||||||
|
|
||||||
#ifdef LOGGING
|
#ifdef LOGGING
|
||||||
static const pn53x_register pn53x_registers[] = {
|
static const pn53x_register pn53x_registers[] = {
|
||||||
|
|
1471
libnfc/chips/pn53x.c
1471
libnfc/chips/pn53x.c
File diff suppressed because it is too large
Load diff
|
@ -127,8 +127,8 @@ typedef enum {
|
||||||
} pn53x_operating_mode;
|
} pn53x_operating_mode;
|
||||||
|
|
||||||
struct pn53x_io {
|
struct pn53x_io {
|
||||||
bool (*send)(nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout);
|
int (*send)(struct nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout);
|
||||||
int (*receive)(nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen, struct timeval *timeout);
|
int (*receive)(struct nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, int timeout);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* defines */
|
/* defines */
|
||||||
|
@ -143,15 +143,17 @@ struct pn53x_data {
|
||||||
/** Current operating mode */
|
/** Current operating mode */
|
||||||
pn53x_operating_mode operating_mode;
|
pn53x_operating_mode operating_mode;
|
||||||
/** Current emulated target */
|
/** Current emulated target */
|
||||||
nfc_target_t* current_target;
|
nfc_target *current_target;
|
||||||
/** PN53x I/O functions stored in struct */
|
/** PN53x I/O functions stored in struct */
|
||||||
const struct pn53x_io * io;
|
const struct pn53x_io *io;
|
||||||
|
/** Last status byte returned by PN53x */
|
||||||
|
uint8_t last_status_byte;
|
||||||
/** Register cache for REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS: The last TX bits setting, we need to reset this if it does not apply anymore */
|
/** Register cache for REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS: The last TX bits setting, we need to reset this if it does not apply anymore */
|
||||||
uint8_t ui8TxBits;
|
uint8_t ui8TxBits;
|
||||||
/** Register cache for SetParameters function. */
|
/** Register cache for SetParameters function. */
|
||||||
uint8_t ui8Parameters;
|
uint8_t ui8Parameters;
|
||||||
/** Last sent command */
|
/** Last sent command */
|
||||||
uint8_t ui8LastCommand;
|
uint8_t last_command;
|
||||||
/** Interframe timer correction */
|
/** Interframe timer correction */
|
||||||
int16_t timer_correction;
|
int16_t timer_correction;
|
||||||
/** Timer prescaler */
|
/** Timer prescaler */
|
||||||
|
@ -160,12 +162,18 @@ struct pn53x_data {
|
||||||
uint8_t wb_data[PN53X_CACHE_REGISTER_SIZE];
|
uint8_t wb_data[PN53X_CACHE_REGISTER_SIZE];
|
||||||
uint8_t wb_mask[PN53X_CACHE_REGISTER_SIZE];
|
uint8_t wb_mask[PN53X_CACHE_REGISTER_SIZE];
|
||||||
bool wb_trigged;
|
bool wb_trigged;
|
||||||
|
/** Command timeout */
|
||||||
|
int timeout_command;
|
||||||
|
/** ATR timeout */
|
||||||
|
int timeout_atr;
|
||||||
|
/** Communication timeout */
|
||||||
|
int timeout_communication;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CHIP_DATA(pnd) ((struct pn53x_data*)(pnd->chip_data))
|
#define CHIP_DATA(pnd) ((struct pn53x_data*)(pnd->chip_data))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum pn53x_modulation_t
|
* @enum pn53x_modulation
|
||||||
* @brief NFC modulation
|
* @brief NFC modulation
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -187,10 +195,10 @@ typedef enum {
|
||||||
PM_ISO14443B_424 = 0x07,
|
PM_ISO14443B_424 = 0x07,
|
||||||
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531 nor PN532) */
|
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531 nor PN532) */
|
||||||
PM_ISO14443B_847 = 0x08,
|
PM_ISO14443B_847 = 0x08,
|
||||||
} pn53x_modulation_t;
|
} pn53x_modulation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum pn53x_target_type_t
|
* @enum pn53x_target_type
|
||||||
* @brief NFC target type enumeration
|
* @brief NFC target type enumeration
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -228,7 +236,7 @@ typedef enum {
|
||||||
PTT_DEP_ACTIVE_212 = 0x81,
|
PTT_DEP_ACTIVE_212 = 0x81,
|
||||||
/** DEP active 424 kbps */
|
/** DEP active 424 kbps */
|
||||||
PTT_DEP_ACTIVE_424 = 0x82,
|
PTT_DEP_ACTIVE_424 = 0x82,
|
||||||
} pn53x_target_type_t;
|
} pn53x_target_type;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PSM_NORMAL = 0x01,
|
PSM_NORMAL = 0x01,
|
||||||
|
@ -238,7 +246,7 @@ typedef enum {
|
||||||
} pn532_sam_mode;
|
} pn532_sam_mode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum pn53x_target_mode_t
|
* @enum pn53x_target_mode
|
||||||
* @brief PN53x target mode enumeration
|
* @brief PN53x target mode enumeration
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -250,104 +258,104 @@ typedef enum {
|
||||||
PTM_DEP_ONLY = 0x02,
|
PTM_DEP_ONLY = 0x02,
|
||||||
/** Configure the PN532 to accept to be initialized only as ISO/IEC14443-4 PICC */
|
/** Configure the PN532 to accept to be initialized only as ISO/IEC14443-4 PICC */
|
||||||
PTM_ISO14443_4_PICC_ONLY = 0x04
|
PTM_ISO14443_4_PICC_ONLY = 0x04
|
||||||
} pn53x_target_mode_t;
|
} pn53x_target_mode;
|
||||||
|
|
||||||
extern const byte_t pn53x_ack_frame[6];
|
extern const uint8_t pn53x_ack_frame[6];
|
||||||
extern const byte_t pn53x_nack_frame[6];
|
extern const uint8_t pn53x_nack_frame[6];
|
||||||
|
|
||||||
bool pn53x_init(nfc_device_t * pnd);
|
int pn53x_init(struct nfc_device *pnd);
|
||||||
bool pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t *pszRx, struct timeval *timeout);
|
int pn53x_transceive (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRxLen, int timeout);
|
||||||
|
|
||||||
bool pn53x_set_parameters (nfc_device_t * pnd, const uint8_t ui8Value, const bool bEnable);
|
int pn53x_set_parameters (struct nfc_device *pnd, const uint8_t ui8Value, const bool bEnable);
|
||||||
bool pn53x_set_tx_bits (nfc_device_t * pnd, const uint8_t ui8Bits);
|
int pn53x_set_tx_bits (struct nfc_device *pnd, const uint8_t ui8Bits);
|
||||||
bool pn53x_wrap_frame (const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, byte_t * pbtFrame,
|
int pn53x_wrap_frame (const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtFrame);
|
||||||
size_t * pszFrameBits);
|
int pn53x_unwrap_frame (const uint8_t *pbtFrame, const size_t szFrameBits, uint8_t *pbtRx, uint8_t *pbtRxPar);
|
||||||
bool pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t * pbtRx, size_t * pszRxBits,
|
int pn53x_decode_target_data (const uint8_t *pbtRawData, size_t szRawData,
|
||||||
byte_t * pbtRxPar);
|
pn53x_type chip_type, nfc_modulation_type nmt,
|
||||||
bool pn53x_decode_target_data (const byte_t * pbtRawData, size_t szRawData,
|
nfc_target_info *pnti);
|
||||||
pn53x_type chip_type, nfc_modulation_type_t nmt,
|
int pn53x_read_register (struct nfc_device *pnd, uint16_t ui16Reg, uint8_t *ui8Value);
|
||||||
nfc_target_info_t * pnti);
|
int pn53x_write_register (struct nfc_device *pnd, uint16_t ui16Reg, uint8_t ui8SymbolMask, uint8_t ui8Value);
|
||||||
bool pn53x_read_register (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t * ui8Value);
|
int pn53x_get_firmware_version (struct nfc_device *pnd, char abtFirmwareText[22]);
|
||||||
bool pn53x_write_register (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t ui8SymbolMask, uint8_t ui8Value);
|
int pn53x_set_property_int (struct nfc_device *pnd, const nfc_property property, const int value);
|
||||||
bool pn53x_get_firmware_version (nfc_device_t * pnd, char abtFirmwareText[22]);
|
int pn53x_set_property_bool (struct nfc_device *pnd, const nfc_property property, const bool bEnable);
|
||||||
bool pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
|
|
||||||
bool pn53x_check_communication (nfc_device_t *pnd);
|
int pn53x_check_communication (struct nfc_device *pnd);
|
||||||
bool pn53x_idle (nfc_device_t * pnd);
|
int pn53x_idle (struct nfc_device *pnd);
|
||||||
|
|
||||||
// NFC device as Initiator functions
|
// NFC device as Initiator functions
|
||||||
bool pn53x_initiator_init (nfc_device_t * pnd);
|
int pn53x_initiator_init (struct nfc_device *pnd);
|
||||||
bool pn53x_initiator_select_passive_target (nfc_device_t * pnd,
|
int pn53x_initiator_select_passive_target (struct nfc_device *pnd,
|
||||||
const nfc_modulation_t nm,
|
const nfc_modulation nm,
|
||||||
const byte_t * pbtInitData, const size_t szInitData,
|
const uint8_t *pbtInitData, const size_t szInitData,
|
||||||
nfc_target_t * pnt);
|
nfc_target *pnt);
|
||||||
bool pn53x_initiator_poll_target (nfc_device_t * pnd,
|
int pn53x_initiator_poll_target (struct nfc_device *pnd,
|
||||||
const nfc_modulation_t * pnmModulations, const size_t szModulations,
|
const nfc_modulation *pnmModulations, const size_t szModulations,
|
||||||
const uint8_t uiPollNr, const uint8_t uiPeriod,
|
const uint8_t uiPollNr, const uint8_t uiPeriod,
|
||||||
nfc_target_t * pnt);
|
nfc_target *pnt);
|
||||||
bool pn53x_initiator_select_dep_target (nfc_device_t * pnd,
|
int pn53x_initiator_select_dep_target (struct nfc_device *pnd,
|
||||||
const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr,
|
const nfc_dep_mode ndm, const nfc_baud_rate nbr,
|
||||||
const nfc_dep_info_t * pndiInitiator,
|
const nfc_dep_info *pndiInitiator,
|
||||||
nfc_target_t * pnt);
|
nfc_target *pnt,
|
||||||
bool pn53x_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits,
|
const int timeout);
|
||||||
const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits,
|
int pn53x_initiator_transceive_bits (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits,
|
||||||
byte_t * pbtRxPar);
|
const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar);
|
||||||
bool pn53x_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx,
|
int pn53x_initiator_transceive_bytes (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx,
|
||||||
byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
|
uint8_t *pbtRx, size_t *pszRx, int timeout);
|
||||||
bool pn53x_initiator_transceive_bits_timed (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits,
|
int pn53x_initiator_transceive_bits_timed (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits,
|
||||||
const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits,
|
const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar, uint32_t *cycles);
|
||||||
byte_t * pbtRxPar, uint32_t * cycles);
|
int pn53x_initiator_transceive_bytes_timed (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx,
|
||||||
bool pn53x_initiator_transceive_bytes_timed (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx,
|
uint8_t *pbtRx, uint32_t *cycles);
|
||||||
byte_t * pbtRx, size_t * pszRx, uint32_t * cycles);
|
int pn53x_initiator_deselect_target (struct nfc_device *pnd);
|
||||||
bool pn53x_initiator_deselect_target (nfc_device_t * pnd);
|
|
||||||
|
|
||||||
// NFC device as Target functions
|
// NFC device as Target functions
|
||||||
bool pn53x_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx);
|
int pn53x_target_init (struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRxLen, int timeout);
|
||||||
bool pn53x_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
|
int pn53x_target_receive_bits (struct nfc_device *pnd, uint8_t *pbtRx, const size_t szRxLen, uint8_t *pbtRxPar);
|
||||||
bool pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
|
int pn53x_target_receive_bytes (struct nfc_device *pnd, uint8_t *pbtRx, const size_t szRxLen, int timeout);
|
||||||
bool pn53x_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar);
|
int pn53x_target_send_bits (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar);
|
||||||
bool pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, struct timeval *timeout);
|
int pn53x_target_send_bytes (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int timeout);
|
||||||
|
|
||||||
// Error handling functions
|
// Error handling functions
|
||||||
const char *pn53x_strerror (const nfc_device_t * pnd);
|
const char *pn53x_strerror (const struct nfc_device *pnd);
|
||||||
|
|
||||||
// C wrappers for PN53x commands
|
// C wrappers for PN53x commands
|
||||||
bool pn53x_SetParameters (nfc_device_t * pnd, const uint8_t ui8Value);
|
int pn53x_SetParameters (struct nfc_device *pnd, const uint8_t ui8Value);
|
||||||
bool pn53x_SAMConfiguration (nfc_device_t * pnd, const pn532_sam_mode mode, struct timeval *timeout);
|
int pn53x_SAMConfiguration (struct nfc_device *pnd, const pn532_sam_mode mode, int timeout);
|
||||||
bool pn53x_PowerDown (nfc_device_t * pnd);
|
int pn53x_PowerDown (struct nfc_device *pnd);
|
||||||
bool pn53x_InListPassiveTarget (nfc_device_t * pnd, const pn53x_modulation_t pmInitModulation,
|
int pn53x_InListPassiveTarget (struct nfc_device *pnd, const pn53x_modulation pmInitModulation,
|
||||||
const byte_t szMaxTargets, const byte_t * pbtInitiatorData,
|
const uint8_t szMaxTargets, const uint8_t *pbtInitiatorData,
|
||||||
const size_t szInitiatorDataLen, byte_t * pbtTargetsData, size_t * pszTargetsData,
|
const size_t szInitiatorDataLen, uint8_t *pbtTargetsData, size_t *pszTargetsData,
|
||||||
struct timeval *timeout);
|
int timeout);
|
||||||
bool pn53x_InDeselect (nfc_device_t * pnd, const uint8_t ui8Target);
|
int pn53x_InDeselect (struct nfc_device *pnd, const uint8_t ui8Target);
|
||||||
bool pn53x_InRelease (nfc_device_t * pnd, const uint8_t ui8Target);
|
int pn53x_InRelease (struct nfc_device *pnd, const uint8_t ui8Target);
|
||||||
bool pn53x_InAutoPoll (nfc_device_t * pnd, const pn53x_target_type_t * ppttTargetTypes, const size_t szTargetTypes,
|
int pn53x_InAutoPoll (struct nfc_device *pnd, const pn53x_target_type *ppttTargetTypes, const size_t szTargetTypes,
|
||||||
const byte_t btPollNr, const byte_t btPeriod, nfc_target_t * pntTargets,
|
const uint8_t btPollNr, const uint8_t btPeriod, nfc_target *pntTargets,
|
||||||
size_t * pszTargetFound);
|
const int timeout);
|
||||||
bool pn53x_InJumpForDEP (nfc_device_t * pnd,
|
int pn53x_InJumpForDEP (struct nfc_device *pnd,
|
||||||
const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr,
|
const nfc_dep_mode ndm, const nfc_baud_rate nbr,
|
||||||
const byte_t * pbtPassiveInitiatorData,
|
const uint8_t *pbtPassiveInitiatorData,
|
||||||
const byte_t * pbtNFCID3i,
|
const uint8_t *pbtNFCID3i,
|
||||||
const byte_t * pbtGB, const size_t szGB,
|
const uint8_t *pbtGB, const size_t szGB,
|
||||||
nfc_target_t * pnt);
|
nfc_target *pnt,
|
||||||
bool pn53x_TgInitAsTarget (nfc_device_t * pnd, pn53x_target_mode_t ptm,
|
const int timeout);
|
||||||
const byte_t * pbtMifareParams,
|
int pn53x_TgInitAsTarget (struct nfc_device *pnd, pn53x_target_mode ptm,
|
||||||
const byte_t * pbtTkt, size_t szTkt,
|
const uint8_t *pbtMifareParams,
|
||||||
const byte_t * pbtFeliCaParams,
|
const uint8_t *pbtTkt, size_t szTkt,
|
||||||
const byte_t * pbtNFCID3t, const byte_t * pbtGB, const size_t szGB,
|
const uint8_t *pbtFeliCaParams,
|
||||||
byte_t * pbtRx, size_t * pszRx, byte_t * pbtModeByte);
|
const uint8_t *pbtNFCID3t, const uint8_t *pbtGB, const size_t szGB,
|
||||||
|
uint8_t *pbtRx, const size_t szRxLen, uint8_t *pbtModeByte, int timeout);
|
||||||
|
|
||||||
// RFConfiguration
|
// RFConfiguration
|
||||||
bool pn53x_RFConfiguration__RF_field (nfc_device_t * pnd, bool bEnable);
|
int pn53x_RFConfiguration__RF_field (struct nfc_device *pnd, bool bEnable);
|
||||||
bool pn53x_RFConfiguration__Various_timings (nfc_device_t * pnd, const uint8_t fATR_RES_Timeout, const uint8_t fRetryTimeout);
|
int pn53x_RFConfiguration__Various_timings (struct nfc_device *pnd, const uint8_t fATR_RES_Timeout, const uint8_t fRetryTimeout);
|
||||||
bool pn53x_RFConfiguration__MaxRtyCOM (nfc_device_t * pnd, const uint8_t MaxRtyCOM);
|
int pn53x_RFConfiguration__MaxRtyCOM (struct nfc_device *pnd, const uint8_t MaxRtyCOM);
|
||||||
bool pn53x_RFConfiguration__MaxRetries (nfc_device_t * pnd, const uint8_t MxRtyATR, const uint8_t MxRtyPSL, const uint8_t MxRtyPassiveActivation);
|
int pn53x_RFConfiguration__MaxRetries (struct nfc_device *pnd, const uint8_t MxRtyATR, const uint8_t MxRtyPSL, const uint8_t MxRtyPassiveActivation);
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
bool pn53x_check_ack_frame (nfc_device_t * pnd, const byte_t * pbtRxFrame, const size_t szRxFrameLen);
|
int pn53x_check_ack_frame (struct nfc_device *pnd, const uint8_t *pbtRxFrame, const size_t szRxFrameLen);
|
||||||
bool pn53x_check_error_frame (nfc_device_t * pnd, const byte_t * pbtRxFrame, const size_t szRxFrameLen);
|
int pn53x_check_error_frame (struct nfc_device *pnd, const uint8_t *pbtRxFrame, const size_t szRxFrameLen);
|
||||||
bool pn53x_build_frame (byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData);
|
int pn53x_build_frame (uint8_t *pbtFrame, size_t *pszFrame, const uint8_t *pbtData, const size_t szData);
|
||||||
|
|
||||||
void pn53x_data_new (nfc_device_t * pnd, const struct pn53x_io* io);
|
void pn53x_data_new (struct nfc_device *pnd, const struct pn53x_io *io);
|
||||||
void pn53x_data_free (nfc_device_t * pnd);
|
void pn53x_data_free (struct nfc_device *pnd);
|
||||||
|
|
||||||
#endif // __NFC_CHIPS_PN53X_H__
|
#endif // __NFC_CHIPS_PN53X_H__
|
||||||
|
|
|
@ -50,6 +50,6 @@
|
||||||
|
|
||||||
# define DRIVERS_MAX_DEVICES 16
|
# define DRIVERS_MAX_DEVICES 16
|
||||||
|
|
||||||
extern const struct nfc_driver_t *nfc_drivers[];
|
extern const struct nfc_driver *nfc_drivers[];
|
||||||
|
|
||||||
#endif // __NFC_DRIVERS_H__
|
#endif // __NFC_DRIVERS_H__
|
||||||
|
|
|
@ -38,8 +38,3 @@ if LIBUSB_ENABLED
|
||||||
libnfcdrivers_la_LIBADD += @libusb_LIBS@
|
libnfcdrivers_la_LIBADD += @libusb_LIBS@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if HAS_LOG4C
|
|
||||||
libnfcdrivers_la_CFLAGS += @log4c_CFLAGS@
|
|
||||||
libnfcdrivers_la_LIBADD += @log4c_LIBS@
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif // HAVE_CONFIG_H
|
#endif // HAVE_CONFIG_H
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
@ -40,7 +41,7 @@
|
||||||
// Bus
|
// Bus
|
||||||
#include <winscard.h>
|
#include <winscard.h>
|
||||||
|
|
||||||
# define ACR122_DRIVER_NAME "ACR122"
|
#define ACR122_DRIVER_NAME "acr122"
|
||||||
|
|
||||||
#if defined (_WIN32)
|
#if defined (_WIN32)
|
||||||
# define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE SCARD_CTL_CODE(3500)
|
# define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE SCARD_CTL_CODE(3500)
|
||||||
|
@ -76,7 +77,7 @@
|
||||||
|
|
||||||
const struct pn53x_io acr122_io;
|
const struct pn53x_io acr122_io;
|
||||||
|
|
||||||
char *acr122_firmware (nfc_device_t *pnd);
|
char *acr122_firmware (nfc_device *pnd);
|
||||||
|
|
||||||
const char *supported_devices[] = {
|
const char *supported_devices[] = {
|
||||||
"ACS ACR122", // ACR122U & Touchatag, last version
|
"ACS ACR122", // ACR122U & Touchatag, last version
|
||||||
|
@ -89,7 +90,7 @@ const char *supported_devices[] = {
|
||||||
struct acr122_data {
|
struct acr122_data {
|
||||||
SCARDHANDLE hCard;
|
SCARDHANDLE hCard;
|
||||||
SCARD_IO_REQUEST ioCard;
|
SCARD_IO_REQUEST ioCard;
|
||||||
byte_t abtRx[ACR122_RESPONSE_LEN];
|
uint8_t abtRx[ACR122_RESPONSE_LEN];
|
||||||
size_t szRx;
|
size_t szRx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,7 +124,7 @@ acr122_free_scardcontext (void)
|
||||||
|
|
||||||
#define PCSC_MAX_DEVICES 16
|
#define PCSC_MAX_DEVICES 16
|
||||||
/**
|
/**
|
||||||
* @brief List connected devices
|
* @brief List opened devices
|
||||||
*
|
*
|
||||||
* Probe PCSC to find NFC capable hardware.
|
* Probe PCSC to find NFC capable hardware.
|
||||||
*
|
*
|
||||||
|
@ -133,7 +134,7 @@ acr122_free_scardcontext (void)
|
||||||
* @return true if succeeded, false otherwise.
|
* @return true if succeeded, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
acr122_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
|
acr122_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t *pszDeviceFound)
|
||||||
{
|
{
|
||||||
size_t szPos = 0;
|
size_t szPos = 0;
|
||||||
char acDeviceNames[256 + 64 * PCSC_MAX_DEVICES];
|
char acDeviceNames[256 + 64 * PCSC_MAX_DEVICES];
|
||||||
|
@ -158,9 +159,7 @@ acr122_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
|
||||||
if (SCardListReaders (*pscc, NULL, acDeviceNames, &dwDeviceNamesLen) != SCARD_S_SUCCESS)
|
if (SCardListReaders (*pscc, NULL, acDeviceNames, &dwDeviceNamesLen) != SCARD_S_SUCCESS)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// DBG("%s", "PCSC reports following device(s):");
|
while ((acDeviceNames[szPos] != '\0') && ((*pszDeviceFound) < connstrings_len)) {
|
||||||
|
|
||||||
while ((acDeviceNames[szPos] != '\0') && ((*pszDeviceFound) < szDevices)) {
|
|
||||||
uiBusIndex++;
|
uiBusIndex++;
|
||||||
|
|
||||||
// DBG("- %s (pos=%ld)", acDeviceNames + szPos, (unsigned long) szPos);
|
// DBG("- %s (pos=%ld)", acDeviceNames + szPos, (unsigned long) szPos);
|
||||||
|
@ -173,9 +172,7 @@ acr122_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
|
||||||
|
|
||||||
if (bSupported) {
|
if (bSupported) {
|
||||||
// Supported ACR122 device found
|
// Supported ACR122 device found
|
||||||
strncpy (pnddDevices[*pszDeviceFound].acDevice, acDeviceNames + szPos, DEVICE_NAME_LENGTH - 1);
|
snprintf (connstrings[*pszDeviceFound], sizeof(nfc_connstring), "%s:%s:%"PRIu32, ACR122_DRIVER_NAME, acDeviceNames + szPos, uiBusIndex);
|
||||||
pnddDevices[*pszDeviceFound].pcDriver = ACR122_DRIVER_NAME;
|
|
||||||
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
|
|
||||||
(*pszDeviceFound)++;
|
(*pszDeviceFound)++;
|
||||||
} else {
|
} else {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "PCSC device [%s] is not NFC capable or not supported by libnfc.", acDeviceNames + szPos);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "PCSC device [%s] is not NFC capable or not supported by libnfc.", acDeviceNames + szPos);
|
||||||
|
@ -189,26 +186,88 @@ acr122_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_device_t *
|
struct acr122_descriptor {
|
||||||
acr122_connect (const nfc_device_desc_t * pndd)
|
char pcsc_device_name[512];
|
||||||
|
int bus_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
acr122_connstring_decode (const nfc_connstring connstring, struct acr122_descriptor *desc)
|
||||||
{
|
{
|
||||||
|
char *cs = malloc (strlen (connstring) + 1);
|
||||||
|
if (!cs) {
|
||||||
|
perror ("malloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy (cs, connstring);
|
||||||
|
const char *driver_name = strtok (cs, ":");
|
||||||
|
if (!driver_name) {
|
||||||
|
// Parse error
|
||||||
|
free (cs);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != strcmp (driver_name, ACR122_DRIVER_NAME)) {
|
||||||
|
// Driver name does not match.
|
||||||
|
free (cs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *device_name = strtok (NULL, ":");
|
||||||
|
if (!device_name) {
|
||||||
|
// Only driver name was specified (or parsing error)
|
||||||
|
free (cs);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strncpy (desc->pcsc_device_name, device_name, sizeof(desc->pcsc_device_name)-1);
|
||||||
|
desc->pcsc_device_name[sizeof(desc->pcsc_device_name)-1] = '\0';
|
||||||
|
|
||||||
|
const char *bus_index_s = strtok (NULL, ":");
|
||||||
|
if (!bus_index_s) {
|
||||||
|
// bus index not specified (or parsing error)
|
||||||
|
free (cs);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
unsigned long bus_index;
|
||||||
|
if (sscanf (bus_index_s, "%lu", &bus_index) != 1) {
|
||||||
|
// bus_index_s is not a number
|
||||||
|
free (cs);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
desc->bus_index = bus_index;
|
||||||
|
|
||||||
|
free (cs);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
nfc_device *
|
||||||
|
acr122_open (const nfc_connstring connstring)
|
||||||
|
{
|
||||||
|
struct acr122_descriptor ndd;
|
||||||
|
int connstring_decode_level = acr122_connstring_decode (connstring, &ndd);
|
||||||
|
|
||||||
|
if (connstring_decode_level < 2) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// FIXME: acr122_open() does not take care about bus index
|
||||||
|
|
||||||
char *pcFirmware;
|
char *pcFirmware;
|
||||||
nfc_device_t *pnd = nfc_device_new ();
|
nfc_device *pnd = nfc_device_new (connstring);
|
||||||
pnd->driver_data = malloc (sizeof (struct acr122_data));
|
pnd->driver_data = malloc (sizeof (struct acr122_data));
|
||||||
|
|
||||||
// Alloc and init chip's data
|
// Alloc and init chip's data
|
||||||
pn53x_data_new (pnd, &acr122_io);
|
pn53x_data_new (pnd, &acr122_io);
|
||||||
|
|
||||||
SCARDCONTEXT *pscc;
|
SCARDCONTEXT *pscc;
|
||||||
|
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to connect to %s", pndd->acDevice);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to open %s", ndd.pcsc_device_name);
|
||||||
// Test if context succeeded
|
// Test if context succeeded
|
||||||
if (!(pscc = acr122_get_scardcontext ()))
|
if (!(pscc = acr122_get_scardcontext ()))
|
||||||
goto error;
|
goto error;
|
||||||
// Test if we were able to connect to the "emulator" card
|
// Test if we were able to connect to the "emulator" card
|
||||||
if (SCardConnect (*pscc, pndd->acDevice, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &(DRIVER_DATA (pnd)->hCard), (void *) &(DRIVER_DATA (pnd)->ioCard.dwProtocol)) != SCARD_S_SUCCESS) {
|
if (SCardConnect (*pscc, ndd.pcsc_device_name, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &(DRIVER_DATA (pnd)->hCard), (void *) &(DRIVER_DATA (pnd)->ioCard.dwProtocol)) != SCARD_S_SUCCESS) {
|
||||||
// Connect to ACR122 firmware version >2.0
|
// Connect to ACR122 firmware version >2.0
|
||||||
if (SCardConnect (*pscc, pndd->acDevice, SCARD_SHARE_DIRECT, 0, &(DRIVER_DATA (pnd)->hCard), (void *) &(DRIVER_DATA (pnd)->ioCard.dwProtocol)) != SCARD_S_SUCCESS) {
|
if (SCardConnect (*pscc, ndd.pcsc_device_name, SCARD_SHARE_DIRECT, 0, &(DRIVER_DATA (pnd)->hCard), (void *) &(DRIVER_DATA (pnd)->ioCard.dwProtocol)) != SCARD_S_SUCCESS) {
|
||||||
// We can not connect to this device.
|
// We can not connect to this device.
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%s", "PCSC connect failed");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%s", "PCSC connect failed");
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -222,7 +281,7 @@ acr122_connect (const nfc_device_desc_t * pndd)
|
||||||
if (strstr (pcFirmware, FIRMWARE_TEXT) != NULL) {
|
if (strstr (pcFirmware, FIRMWARE_TEXT) != NULL) {
|
||||||
|
|
||||||
// Done, we found the reader we are looking for
|
// Done, we found the reader we are looking for
|
||||||
snprintf (pnd->acName, sizeof (pnd->acName), "%s / %s", pndd->acDevice, pcFirmware);
|
snprintf (pnd->name, sizeof (pnd->name), "%s / %s", ndd.pcsc_device_name, pcFirmware);
|
||||||
|
|
||||||
// 50: empirical tuning on Touchatag
|
// 50: empirical tuning on Touchatag
|
||||||
// 46: empirical tuning on ACR122U
|
// 46: empirical tuning on ACR122U
|
||||||
|
@ -242,7 +301,7 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
acr122_disconnect (nfc_device_t * pnd)
|
acr122_close (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
SCardDisconnect (DRIVER_DATA (pnd)->hCard, SCARD_LEAVE_CARD);
|
SCardDisconnect (DRIVER_DATA (pnd)->hCard, SCARD_LEAVE_CARD);
|
||||||
acr122_free_scardcontext ();
|
acr122_free_scardcontext ();
|
||||||
|
@ -251,21 +310,21 @@ acr122_disconnect (nfc_device_t * pnd)
|
||||||
nfc_device_free (pnd);
|
nfc_device_free (pnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int
|
||||||
acr122_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout)
|
acr122_send (nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout)
|
||||||
{
|
{
|
||||||
// FIXME: timeout is not handled
|
// FIXME: timeout is not handled
|
||||||
(void) timeout;
|
(void) timeout;
|
||||||
|
|
||||||
// Make sure the command does not overflow the send buffer
|
// Make sure the command does not overflow the send buffer
|
||||||
if (szData > ACR122_COMMAND_LEN) {
|
if (szData > ACR122_COMMAND_LEN) {
|
||||||
pnd->iLastError = EINVALARG;
|
pnd->last_error = NFC_EINVARG;
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare and transmit the send buffer
|
// Prepare and transmit the send buffer
|
||||||
const size_t szTxBuf = szData + 6;
|
const size_t szTxBuf = szData + 6;
|
||||||
byte_t abtTxBuf[ACR122_WRAP_LEN + ACR122_COMMAND_LEN] = { 0xFF, 0x00, 0x00, 0x00, szData + 1, 0xD4 };
|
uint8_t abtTxBuf[ACR122_WRAP_LEN + ACR122_COMMAND_LEN] = { 0xFF, 0x00, 0x00, 0x00, szData + 1, 0xD4 };
|
||||||
memcpy (abtTxBuf + 6, pbtData, szData);
|
memcpy (abtTxBuf + 6, pbtData, szData);
|
||||||
LOG_HEX ("TX", abtTxBuf, szTxBuf);
|
LOG_HEX ("TX", abtTxBuf, szTxBuf);
|
||||||
|
|
||||||
|
@ -286,8 +345,8 @@ acr122_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, st
|
||||||
* field.
|
* field.
|
||||||
*/
|
*/
|
||||||
if (SCardControl (DRIVER_DATA (pnd)->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtTxBuf, szTxBuf, DRIVER_DATA (pnd)->abtRx, ACR122_RESPONSE_LEN, &dwRxLen) != SCARD_S_SUCCESS) {
|
if (SCardControl (DRIVER_DATA (pnd)->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtTxBuf, szTxBuf, DRIVER_DATA (pnd)->abtRx, ACR122_RESPONSE_LEN, &dwRxLen) != SCARD_S_SUCCESS) {
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
@ -295,8 +354,8 @@ acr122_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, st
|
||||||
* receive the response from the PN532.
|
* receive the response from the PN532.
|
||||||
*/
|
*/
|
||||||
if (SCardTransmit (DRIVER_DATA (pnd)->hCard, &(DRIVER_DATA (pnd)->ioCard), abtTxBuf, szTxBuf, NULL, DRIVER_DATA (pnd)->abtRx, &dwRxLen) != SCARD_S_SUCCESS) {
|
if (SCardTransmit (DRIVER_DATA (pnd)->hCard, &(DRIVER_DATA (pnd)->ioCard), abtTxBuf, szTxBuf, NULL, DRIVER_DATA (pnd)->abtRx, &dwRxLen) != SCARD_S_SUCCESS) {
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,29 +366,29 @@ acr122_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, st
|
||||||
|
|
||||||
// Make sure we received the byte-count we expected
|
// Make sure we received the byte-count we expected
|
||||||
if (dwRxLen != 2) {
|
if (dwRxLen != 2) {
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
// Check if the operation was successful, so an answer is available
|
// Check if the operation was successful, so an answer is available
|
||||||
if (DRIVER_DATA (pnd)->abtRx[0] == SCARD_OPERATION_ERROR) {
|
if (DRIVER_DATA (pnd)->abtRx[0] == SCARD_OPERATION_ERROR) {
|
||||||
pnd->iLastError = EFRAISERRFRAME;
|
pnd->last_error = NFC_EIO;
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DRIVER_DATA (pnd)->szRx = dwRxLen;
|
DRIVER_DATA (pnd)->szRx = dwRxLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return NFC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
acr122_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struct timeval *timeout)
|
acr122_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szData, int timeout)
|
||||||
{
|
{
|
||||||
// FIXME: timeout is not handled
|
// FIXME: timeout is not handled
|
||||||
(void) timeout;
|
(void) timeout;
|
||||||
|
|
||||||
int len;
|
int len;
|
||||||
byte_t abtRxCmd[5] = { 0xFF, 0xC0, 0x00, 0x00 };
|
uint8_t abtRxCmd[5] = { 0xFF, 0xC0, 0x00, 0x00 };
|
||||||
|
|
||||||
if (DRIVER_DATA (pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_T0) {
|
if (DRIVER_DATA (pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_T0) {
|
||||||
/*
|
/*
|
||||||
|
@ -338,8 +397,8 @@ acr122_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struc
|
||||||
DWORD dwRxLen = sizeof (DRIVER_DATA (pnd)->abtRx);
|
DWORD dwRxLen = sizeof (DRIVER_DATA (pnd)->abtRx);
|
||||||
abtRxCmd[4] = DRIVER_DATA (pnd)->abtRx[1];
|
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) {
|
if (SCardTransmit (DRIVER_DATA (pnd)->hCard, &(DRIVER_DATA (pnd)->ioCard), abtRxCmd, sizeof (abtRxCmd), NULL, DRIVER_DATA (pnd)->abtRx, &dwRxLen) != SCARD_S_SUCCESS) {
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
DRIVER_DATA (pnd)->szRx = dwRxLen;
|
DRIVER_DATA (pnd)->szRx = dwRxLen;
|
||||||
} else {
|
} else {
|
||||||
|
@ -351,31 +410,29 @@ acr122_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struc
|
||||||
|
|
||||||
// Make sure we have an emulated answer that fits the return buffer
|
// Make sure we have an emulated answer that fits the return buffer
|
||||||
if (DRIVER_DATA (pnd)->szRx < 4 || (DRIVER_DATA (pnd)->szRx - 4) > szData) {
|
if (DRIVER_DATA (pnd)->szRx < 4 || (DRIVER_DATA (pnd)->szRx - 4) > szData) {
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
// Wipe out the 4 APDU emulation bytes: D5 4B .. .. .. 90 00
|
// Wipe out the 4 APDU emulation bytes: D5 4B .. .. .. 90 00
|
||||||
len = DRIVER_DATA (pnd)->szRx - 4;
|
len = DRIVER_DATA (pnd)->szRx - 4;
|
||||||
memcpy (pbtData, DRIVER_DATA (pnd)->abtRx + 2, len);
|
memcpy (pbtData, DRIVER_DATA (pnd)->abtRx + 2, len);
|
||||||
|
|
||||||
// Transmission went successful
|
|
||||||
pnd->iLastError = 0;
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
acr122_firmware (nfc_device_t *pnd)
|
acr122_firmware (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
byte_t abtGetFw[5] = { 0xFF, 0x00, 0x48, 0x00, 0x00 };
|
uint8_t abtGetFw[5] = { 0xFF, 0x00, 0x48, 0x00, 0x00 };
|
||||||
uint32_t uiResult;
|
uint32_t uiResult;
|
||||||
|
|
||||||
static char abtFw[11];
|
static char abtFw[11];
|
||||||
DWORD dwFwLen = sizeof (abtFw);
|
DWORD dwFwLen = sizeof (abtFw);
|
||||||
memset (abtFw, 0x00, sizeof (abtFw));
|
memset (abtFw, 0x00, sizeof (abtFw));
|
||||||
if (DRIVER_DATA (pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
|
if (DRIVER_DATA (pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
|
||||||
uiResult = SCardControl (DRIVER_DATA (pnd)->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtGetFw, sizeof (abtGetFw), (byte_t *) abtFw, dwFwLen-1, &dwFwLen);
|
uiResult = SCardControl (DRIVER_DATA (pnd)->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtGetFw, sizeof (abtGetFw), (uint8_t *) abtFw, dwFwLen-1, &dwFwLen);
|
||||||
} else {
|
} else {
|
||||||
uiResult = SCardTransmit (DRIVER_DATA (pnd)->hCard, &(DRIVER_DATA (pnd)->ioCard), abtGetFw, sizeof (abtGetFw), NULL, (byte_t *) abtFw, &dwFwLen);
|
uiResult = SCardTransmit (DRIVER_DATA (pnd)->hCard, &(DRIVER_DATA (pnd)->ioCard), abtGetFw, sizeof (abtGetFw), NULL, (uint8_t *) abtFw, &dwFwLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uiResult != SCARD_S_SUCCESS) {
|
if (uiResult != SCARD_S_SUCCESS) {
|
||||||
|
@ -387,10 +444,10 @@ acr122_firmware (nfc_device_t *pnd)
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
bool
|
bool
|
||||||
acr122_led_red (nfc_device_t *pnd, bool bOn)
|
acr122_led_red (nfc_device *pnd, bool bOn)
|
||||||
{
|
{
|
||||||
byte_t abtLed[9] = { 0xFF, 0x00, 0x40, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t abtLed[9] = { 0xFF, 0x00, 0x40, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00 };
|
||||||
byte_t abtBuf[2];
|
uint8_t abtBuf[2];
|
||||||
DWORD dwBufLen = sizeof (abtBuf);
|
DWORD dwBufLen = sizeof (abtBuf);
|
||||||
(void) bOn;
|
(void) bOn;
|
||||||
if (DRIVER_DATA (pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
|
if (DRIVER_DATA (pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
|
||||||
|
@ -406,12 +463,12 @@ const struct pn53x_io acr122_io = {
|
||||||
.receive = acr122_receive,
|
.receive = acr122_receive,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct nfc_driver_t acr122_driver = {
|
const struct nfc_driver acr122_driver = {
|
||||||
.name = ACR122_DRIVER_NAME,
|
.name = ACR122_DRIVER_NAME,
|
||||||
.probe = acr122_probe,
|
.probe = acr122_probe,
|
||||||
.connect = acr122_connect,
|
.open = acr122_open,
|
||||||
.disconnect = acr122_disconnect,
|
.close = acr122_close,
|
||||||
.strerror = pn53x_strerror,
|
.strerror = pn53x_strerror,
|
||||||
|
|
||||||
.initiator_init = pn53x_initiator_init,
|
.initiator_init = pn53x_initiator_init,
|
||||||
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
||||||
|
@ -429,9 +486,10 @@ const struct nfc_driver_t acr122_driver = {
|
||||||
.target_send_bits = pn53x_target_send_bits,
|
.target_send_bits = pn53x_target_send_bits,
|
||||||
.target_receive_bits = pn53x_target_receive_bits,
|
.target_receive_bits = pn53x_target_receive_bits,
|
||||||
|
|
||||||
.configure = pn53x_configure,
|
.device_set_property_bool = pn53x_set_property_bool,
|
||||||
|
.device_set_property_int = pn53x_set_property_int,
|
||||||
|
|
||||||
.abort_command = NULL,
|
.abort_command = NULL, // FIXME: abort is not supported in this driver
|
||||||
.idle = NULL,
|
.idle = NULL, // FIXME: idle is not supported in this driver
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,14 +26,14 @@
|
||||||
|
|
||||||
# include <nfc/nfc-types.h>
|
# include <nfc/nfc-types.h>
|
||||||
|
|
||||||
bool acr122_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
|
bool acr122_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t *pszDeviceFound);
|
||||||
|
|
||||||
// Functions used by developer to handle connection to this device
|
// Functions used by developer to handle connection to this device
|
||||||
nfc_device_t *acr122_connect (const nfc_device_desc_t * pndd);
|
nfc_device *acr122_open (const nfc_connstring connstring);
|
||||||
bool acr122_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout);
|
int acr122_send (nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout);
|
||||||
int acr122_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struct timeval *timeout);
|
int acr122_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szData, int timeout);
|
||||||
void acr122_disconnect (nfc_device_t * pnd);
|
void acr122_close (nfc_device *pnd);
|
||||||
|
|
||||||
extern const struct nfc_driver_t acr122_driver;
|
extern const struct nfc_driver acr122_driver;
|
||||||
|
|
||||||
#endif // ! __NFC_DRIVER_ACR122_H__
|
#endif // ! __NFC_DRIVER_ACR122_H__
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
#include "acr122s.h"
|
#include "acr122s.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/param.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -46,7 +49,7 @@
|
||||||
|
|
||||||
struct acr122s_data {
|
struct acr122s_data {
|
||||||
serial_port port;
|
serial_port port;
|
||||||
byte_t seq;
|
uint8_t seq;
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
int abort_fds[2];
|
int abort_fds[2];
|
||||||
#else
|
#else
|
||||||
|
@ -84,74 +87,74 @@ enum {
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
struct icc_power_on_req {
|
struct icc_power_on_req {
|
||||||
byte_t message_type;
|
uint8_t message_type;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
byte_t slot;
|
uint8_t slot;
|
||||||
byte_t seq;
|
uint8_t seq;
|
||||||
byte_t power_select;
|
uint8_t power_select;
|
||||||
byte_t rfu[2];
|
uint8_t rfu[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct icc_power_on_res {
|
struct icc_power_on_res {
|
||||||
byte_t message_type;
|
uint8_t message_type;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
byte_t slot;
|
uint8_t slot;
|
||||||
byte_t seq;
|
uint8_t seq;
|
||||||
byte_t status;
|
uint8_t status;
|
||||||
byte_t error;
|
uint8_t error;
|
||||||
byte_t chain_parameter;
|
uint8_t chain_parameter;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct icc_power_off_req {
|
struct icc_power_off_req {
|
||||||
byte_t message_type;
|
uint8_t message_type;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
byte_t slot;
|
uint8_t slot;
|
||||||
byte_t seq;
|
uint8_t seq;
|
||||||
byte_t rfu[3];
|
uint8_t rfu[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct icc_power_off_res {
|
struct icc_power_off_res {
|
||||||
byte_t message_type;
|
uint8_t message_type;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
byte_t slot;
|
uint8_t slot;
|
||||||
byte_t seq;
|
uint8_t seq;
|
||||||
byte_t status;
|
uint8_t status;
|
||||||
byte_t error;
|
uint8_t error;
|
||||||
byte_t clock_status;
|
uint8_t clock_status;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xfr_block_req {
|
struct xfr_block_req {
|
||||||
byte_t message_type;
|
uint8_t message_type;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
byte_t slot;
|
uint8_t slot;
|
||||||
byte_t seq;
|
uint8_t seq;
|
||||||
byte_t bwi;
|
uint8_t bwi;
|
||||||
byte_t rfu[2];
|
uint8_t rfu[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xfr_block_res {
|
struct xfr_block_res {
|
||||||
byte_t message_type;
|
uint8_t message_type;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
byte_t slot;
|
uint8_t slot;
|
||||||
byte_t seq;
|
uint8_t seq;
|
||||||
byte_t status;
|
uint8_t status;
|
||||||
byte_t error;
|
uint8_t error;
|
||||||
byte_t chain_parameter;
|
uint8_t chain_parameter;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct apdu_header {
|
struct apdu_header {
|
||||||
byte_t class;
|
uint8_t class;
|
||||||
byte_t ins;
|
uint8_t ins;
|
||||||
byte_t p1;
|
uint8_t p1;
|
||||||
byte_t p2;
|
uint8_t p2;
|
||||||
byte_t length;
|
uint8_t length;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
#define TRACE do { printf("%s:%d\n", __func__, __LINE__); } while (0)
|
#define TRACE do { printf("%s:%d\n", __func__, __LINE__); } while (0)
|
||||||
|
|
||||||
#define DRIVER_DATA(dev) ((struct acr122s_data *) (dev->driver_data))
|
#define DRIVER_DATA(pnd) ((struct acr122s_data *) (pnd->driver_data))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print a debuggin hex string to stdout.
|
* Print a debuggin hex string to stdout.
|
||||||
|
@ -162,7 +165,7 @@ struct apdu_header {
|
||||||
*/
|
*/
|
||||||
#if 0
|
#if 0
|
||||||
static void
|
static void
|
||||||
print_hex(const char *caption, byte_t *buf, size_t buf_len)
|
print_hex(const char *caption, uint8_t *buf, size_t buf_len)
|
||||||
{
|
{
|
||||||
printf("%s:", caption);
|
printf("%s:", caption);
|
||||||
for (size_t i = 0; i < buf_len; i++) {
|
for (size_t i = 0; i < buf_len; i++) {
|
||||||
|
@ -179,53 +182,55 @@ print_hex(const char *caption, byte_t *buf, size_t buf_len)
|
||||||
* @note command frame length (uint32_t at offset 2) should be valid
|
* @note command frame length (uint32_t at offset 2) should be valid
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
acr122s_fix_frame(byte_t *frame)
|
acr122s_fix_frame(uint8_t *frame)
|
||||||
{
|
{
|
||||||
size_t frame_size = FRAME_SIZE(frame);
|
size_t frame_size = FRAME_SIZE(frame);
|
||||||
frame[0] = STX;
|
frame[0] = STX;
|
||||||
frame[frame_size - 1] = ETX;
|
frame[frame_size - 1] = ETX;
|
||||||
|
|
||||||
byte_t *csum = frame + frame_size - 2;
|
uint8_t *csum = frame + frame_size - 2;
|
||||||
*csum = 0;
|
*csum = 0;
|
||||||
for (byte_t *p = frame + 1; p < csum; p++)
|
for (uint8_t *p = frame + 1; p < csum; p++)
|
||||||
*csum ^= *p;
|
*csum ^= *p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a command frame to ACR122S and check its ACK status.
|
* Send a command frame to ACR122S and check its ACK status.
|
||||||
*
|
*
|
||||||
* @param: dev is target nfc device
|
* @param: pnd is target nfc device
|
||||||
* @param: cmd is command frame to send
|
* @param: cmd is command frame to send
|
||||||
* @param: timeout
|
* @param: timeout
|
||||||
* @return 0 if success
|
* @return 0 if success
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
acr122s_send_frame(nfc_device_t *dev, byte_t *frame, struct timeval *timeout)
|
acr122s_send_frame(nfc_device *pnd, uint8_t *frame, int timeout)
|
||||||
{
|
{
|
||||||
size_t frame_size = FRAME_SIZE(frame);
|
size_t frame_size = FRAME_SIZE(frame);
|
||||||
byte_t ack[4];
|
uint8_t ack[4];
|
||||||
byte_t positive_ack[4] = { STX, 0, 0, ETX };
|
uint8_t positive_ack[4] = { STX, 0, 0, ETX };
|
||||||
serial_port port = DRIVER_DATA(dev)->port;
|
serial_port port = DRIVER_DATA(pnd)->port;
|
||||||
int ret;
|
int ret;
|
||||||
void *abort_p;
|
void *abort_p;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
abort_p = &(DRIVER_DATA(dev)->abort_fds[1]);
|
abort_p = &(DRIVER_DATA(pnd)->abort_fds[1]);
|
||||||
#else
|
#else
|
||||||
abort_p = &(DRIVER_DATA(dev)->abort_flag);
|
abort_p = &(DRIVER_DATA(pnd)->abort_flag);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((ret = uart_send(port, frame, frame_size, timeout)) != 0)
|
if ((ret = uart_send(port, frame, frame_size, timeout)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if ((ret = uart_receive(port, ack, 4, abort_p, timeout)) != 0)
|
if ((ret = uart_receive(port, ack, 4, abort_p, timeout)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (memcmp(ack, positive_ack, 4) != 0)
|
if (memcmp(ack, positive_ack, 4) != 0){
|
||||||
return ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
|
return pnd->last_error;
|
||||||
|
}
|
||||||
|
|
||||||
struct xfr_block_req *req = (struct xfr_block_req *) &frame[1];
|
struct xfr_block_req *req = (struct xfr_block_req *) &frame[1];
|
||||||
DRIVER_DATA(dev)->seq = req->seq + 1;
|
DRIVER_DATA(pnd)->seq = req->seq + 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -233,7 +238,7 @@ acr122s_send_frame(nfc_device_t *dev, byte_t *frame, struct timeval *timeout)
|
||||||
/**
|
/**
|
||||||
* Receive response frame after a successfull acr122s_send_command().
|
* Receive response frame after a successfull acr122s_send_command().
|
||||||
*
|
*
|
||||||
* @param: dev is target nfc device
|
* @param: pnd is target nfc device
|
||||||
* @param: frame is buffer where received response frame will be stored
|
* @param: frame is buffer where received response frame will be stored
|
||||||
* @param: frame_size is frame size
|
* @param: frame_size is frame size
|
||||||
* @param: abort_p
|
* @param: abort_p
|
||||||
|
@ -243,29 +248,33 @@ acr122s_send_frame(nfc_device_t *dev, byte_t *frame, struct timeval *timeout)
|
||||||
* @return 0 if success
|
* @return 0 if success
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
acr122s_recv_frame(nfc_device_t *dev, byte_t *frame, size_t frame_size, void *abort_p, struct timeval *timeout)
|
acr122s_recv_frame(nfc_device *pnd, uint8_t *frame, size_t frame_size, void *abort_p, int timeout)
|
||||||
{
|
{
|
||||||
if (frame_size < 13)
|
if (frame_size < 13)
|
||||||
return EINVALARG;
|
pnd->last_error = NFC_EINVARG;
|
||||||
|
return pnd->last_error;
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
serial_port port = DRIVER_DATA(dev)->port;
|
serial_port port = DRIVER_DATA(pnd)->port;
|
||||||
|
|
||||||
if ((ret = uart_receive(port, frame, 11, abort_p, timeout)) != 0)
|
if ((ret = uart_receive(port, frame, 11, abort_p, timeout)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
// Is buffer sufficient to store response?
|
// Is buffer sufficient to store response?
|
||||||
if (frame_size < FRAME_SIZE(frame))
|
if (frame_size < FRAME_SIZE(frame)){
|
||||||
return ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
|
return pnd->last_error;
|
||||||
|
}
|
||||||
|
|
||||||
size_t remaining = FRAME_SIZE(frame) - 11;
|
size_t remaining = FRAME_SIZE(frame) - 11;
|
||||||
if ((ret = uart_receive(port, frame + 11, remaining, abort_p, timeout)) != 0)
|
if ((ret = uart_receive(port, frame + 11, remaining, abort_p, timeout)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
struct xfr_block_res *res = (struct xfr_block_res *) &frame[1];
|
struct xfr_block_res *res = (struct xfr_block_res *) &frame[1];
|
||||||
if ((byte_t) (res->seq + 1) != DRIVER_DATA(dev)->seq) {
|
if ((uint8_t) (res->seq + 1) != DRIVER_DATA(pnd)->seq) {
|
||||||
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Invalid response sequence number.");
|
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Invalid response sequence number.");
|
||||||
return ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -279,7 +288,7 @@ acr122s_recv_frame(nfc_device_t *dev, byte_t *frame, size_t frame_size, void *ab
|
||||||
static uint32_t
|
static uint32_t
|
||||||
le32(uint32_t val) {
|
le32(uint32_t val) {
|
||||||
uint32_t res;
|
uint32_t res;
|
||||||
byte_t *p = (byte_t *) &res;
|
uint8_t *p = (uint8_t *) &res;
|
||||||
p[0] = val;
|
p[0] = val;
|
||||||
p[1] = val >> 8;
|
p[1] = val >> 8;
|
||||||
p[2] = val >> 16;
|
p[2] = val >> 16;
|
||||||
|
@ -290,7 +299,7 @@ le32(uint32_t val) {
|
||||||
/**
|
/**
|
||||||
* Build an ACR122S command frame from a PN532 command.
|
* Build an ACR122S command frame from a PN532 command.
|
||||||
*
|
*
|
||||||
* @param dev is device for which the command frame will be generated
|
* @param pnd is device for which the command frame will be generated
|
||||||
* @param frame is where the resulting command frame will be generated
|
* @param frame is where the resulting command frame will be generated
|
||||||
* @param frame_size is the passed command frame size
|
* @param frame_size is the passed command frame size
|
||||||
* @param p1
|
* @param p1
|
||||||
|
@ -302,9 +311,9 @@ le32(uint32_t val) {
|
||||||
* @return true if frame built successfully
|
* @return true if frame built successfully
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
acr122s_build_frame(nfc_device_t *dev,
|
acr122s_build_frame(nfc_device *pnd,
|
||||||
byte_t *frame, size_t frame_size, byte_t p1, byte_t p2,
|
uint8_t *frame, size_t frame_size, uint8_t p1, uint8_t p2,
|
||||||
const byte_t *data, size_t data_size, int should_prefix)
|
const uint8_t *data, size_t data_size, int should_prefix)
|
||||||
{
|
{
|
||||||
if (frame_size < data_size + APDU_OVERHEAD + should_prefix)
|
if (frame_size < data_size + APDU_OVERHEAD + should_prefix)
|
||||||
return false;
|
return false;
|
||||||
|
@ -315,7 +324,7 @@ acr122s_build_frame(nfc_device_t *dev,
|
||||||
req->message_type = XFR_BLOCK_REQ_MSG;
|
req->message_type = XFR_BLOCK_REQ_MSG;
|
||||||
req->length = le32(5 + data_size + should_prefix);
|
req->length = le32(5 + data_size + should_prefix);
|
||||||
req->slot = 0;
|
req->slot = 0;
|
||||||
req->seq = DRIVER_DATA(dev)->seq;
|
req->seq = DRIVER_DATA(pnd)->seq;
|
||||||
req->bwi = 0;
|
req->bwi = 0;
|
||||||
req->rfu[0] = 0;
|
req->rfu[0] = 0;
|
||||||
req->rfu[1] = 0;
|
req->rfu[1] = 0;
|
||||||
|
@ -327,7 +336,7 @@ acr122s_build_frame(nfc_device_t *dev,
|
||||||
header->p2 = p2;
|
header->p2 = p2;
|
||||||
header->length = data_size + should_prefix;
|
header->length = data_size + should_prefix;
|
||||||
|
|
||||||
byte_t *buf = (byte_t *) &frame[16];
|
uint8_t *buf = (uint8_t *) &frame[16];
|
||||||
if (should_prefix)
|
if (should_prefix)
|
||||||
*buf++ = 0xD4;
|
*buf++ = 0xD4;
|
||||||
memcpy(buf, data, data_size);
|
memcpy(buf, data, data_size);
|
||||||
|
@ -337,61 +346,61 @@ acr122s_build_frame(nfc_device_t *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
acr122s_activate_sam(nfc_device_t *dev)
|
acr122s_activate_sam(nfc_device *pnd)
|
||||||
{
|
{
|
||||||
byte_t cmd[13];
|
uint8_t cmd[13];
|
||||||
memset(cmd, 0, sizeof(cmd));
|
memset(cmd, 0, sizeof(cmd));
|
||||||
cmd[1] = ICC_POWER_ON_REQ_MSG;
|
cmd[1] = ICC_POWER_ON_REQ_MSG;
|
||||||
acr122s_fix_frame(cmd);
|
acr122s_fix_frame(cmd);
|
||||||
|
|
||||||
byte_t resp[MAX_FRAME_SIZE];
|
uint8_t resp[MAX_FRAME_SIZE];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((ret = acr122s_send_frame(dev, cmd, 0)) != 0)
|
if ((ret = acr122s_send_frame(pnd, cmd, 0)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if ((ret = acr122s_recv_frame(dev, resp, MAX_FRAME_SIZE, 0, 0)) != 0)
|
if ((ret = acr122s_recv_frame(pnd, resp, MAX_FRAME_SIZE, 0, 0)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
CHIP_DATA(dev)->power_mode = NORMAL;
|
CHIP_DATA(pnd)->power_mode = NORMAL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
acr122s_deactivate_sam(nfc_device_t *dev)
|
acr122s_deactivate_sam(nfc_device *pnd)
|
||||||
{
|
{
|
||||||
byte_t cmd[13];
|
uint8_t cmd[13];
|
||||||
memset(cmd, 0, sizeof(cmd));
|
memset(cmd, 0, sizeof(cmd));
|
||||||
cmd[1] = ICC_POWER_OFF_REQ_MSG;
|
cmd[1] = ICC_POWER_OFF_REQ_MSG;
|
||||||
acr122s_fix_frame(cmd);
|
acr122s_fix_frame(cmd);
|
||||||
|
|
||||||
byte_t resp[MAX_FRAME_SIZE];
|
uint8_t resp[MAX_FRAME_SIZE];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((ret = acr122s_send_frame(dev, cmd, 0)) != 0)
|
if ((ret = acr122s_send_frame(pnd, cmd, 0)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if ((ret = acr122s_recv_frame(dev, resp, MAX_FRAME_SIZE, 0, 0)) != 0)
|
if ((ret = acr122s_recv_frame(pnd, resp, MAX_FRAME_SIZE, 0, 0)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
CHIP_DATA(dev)->power_mode = LOWVBAT;
|
CHIP_DATA(pnd)->power_mode = LOWVBAT;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
acr122s_get_firmware_version(nfc_device_t *dev, char *version, size_t length)
|
acr122s_get_firmware_version(nfc_device *pnd, char *version, size_t length)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
byte_t cmd[MAX_FRAME_SIZE];
|
uint8_t cmd[MAX_FRAME_SIZE];
|
||||||
|
|
||||||
acr122s_build_frame(dev, cmd, sizeof(cmd), 0x48, 0, NULL, 0, 0);
|
acr122s_build_frame(pnd, cmd, sizeof(cmd), 0x48, 0, NULL, 0, 0);
|
||||||
|
|
||||||
if ((ret = acr122s_send_frame(dev, cmd, 0)) != 0)
|
if ((ret = acr122s_send_frame(pnd, cmd, 0)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if ((ret = acr122s_recv_frame(dev, cmd, sizeof(cmd), 0, 0)) != 0)
|
if ((ret = acr122s_recv_frame(pnd, cmd, sizeof(cmd), 0, 0)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
size_t len = APDU_SIZE(cmd);
|
size_t len = APDU_SIZE(cmd);
|
||||||
|
@ -403,208 +412,277 @@ acr122s_get_firmware_version(nfc_device_t *dev, char *version, size_t length)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct acr122s_descriptor {
|
||||||
|
char port[128];
|
||||||
|
uint32_t speed;
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
acr122s_connstring_decode (const nfc_connstring connstring, struct acr122s_descriptor *desc)
|
||||||
|
{
|
||||||
|
char *cs = malloc (strlen (connstring) + 1);
|
||||||
|
if (!cs) {
|
||||||
|
perror ("malloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy (cs, connstring);
|
||||||
|
const char *driver_name = strtok (cs, ":");
|
||||||
|
if (!driver_name) {
|
||||||
|
// Parse error
|
||||||
|
free (cs);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != strcmp (driver_name, ACR122S_DRIVER_NAME)) {
|
||||||
|
// Driver name does not match.
|
||||||
|
free (cs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *port = strtok (NULL, ":");
|
||||||
|
if (!port) {
|
||||||
|
// Only driver name was specified (or parsing error)
|
||||||
|
free (cs);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strncpy (desc->port, port, sizeof(desc->port)-1);
|
||||||
|
desc->port[sizeof(desc->port)-1] = '\0';
|
||||||
|
|
||||||
|
const char *speed_s = strtok (NULL, ":");
|
||||||
|
if (!speed_s) {
|
||||||
|
// speed not specified (or parsing error)
|
||||||
|
free (cs);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
unsigned long speed;
|
||||||
|
if (sscanf (speed_s, "%lu", &speed) != 1) {
|
||||||
|
// speed_s is not a number
|
||||||
|
free (cs);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
desc->speed = speed;
|
||||||
|
|
||||||
|
free (cs);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
acr122s_probe(nfc_device_desc_t descs[], size_t desc_count, size_t *dev_found)
|
acr122s_probe(nfc_connstring connstrings[], size_t connstrings_len, size_t *pszDeviceFound)
|
||||||
{
|
{
|
||||||
/** @note: Due to UART bus we can't know if its really an ACR122S without
|
/** @note: Due to UART bus we can't know if its really an ACR122S without
|
||||||
* sending some commands. But using this way to probe devices, we can
|
* sending some commands. But using this way to probe devices, we can
|
||||||
* have serious problem with other device on this bus */
|
* have serious problem with other device on this bus */
|
||||||
#ifndef SERIAL_AUTOPROBE_ENABLED
|
#ifndef SERIAL_AUTOPROBE_ENABLED
|
||||||
(void) descs;
|
(void) connstrings;
|
||||||
(void) desc_count;
|
(void) connstrings_len;
|
||||||
*dev_found = 0;
|
*pszDeviceFound = 0;
|
||||||
log_put(LOG_CATEGORY, NFC_PRIORITY_INFO, "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
|
log_put(LOG_CATEGORY, NFC_PRIORITY_INFO, "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
|
||||||
return false;
|
return false;
|
||||||
#else /* SERIAL_AUTOPROBE_ENABLED */
|
#else /* SERIAL_AUTOPROBE_ENABLED */
|
||||||
*dev_found = 0;
|
*pszDeviceFound = 0;
|
||||||
char **ports = uart_list_ports();
|
|
||||||
for (int i = 0; ports[i]; i++) {
|
serial_port sp;
|
||||||
char *port = ports[i];
|
char **acPorts = uart_list_ports ();
|
||||||
serial_port sp = uart_open(port);
|
const char *acPort;
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Trying to find ACR122S device on serial port: %s at %d bauds.", port, ACR122S_DEFAULT_SPEED);
|
int iDevice = 0;
|
||||||
|
|
||||||
|
while ((acPort = acPorts[iDevice++])) {
|
||||||
|
sp = uart_open (acPort);
|
||||||
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Trying to find ACR122S device on serial port: %s at %d bauds.", acPort, ACR122S_DEFAULT_SPEED);
|
||||||
|
|
||||||
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
|
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
|
||||||
uart_flush_input(sp);
|
// We need to flush input to be sure first reply does not comes from older byte transceive
|
||||||
uart_set_speed(sp, ACR122S_DEFAULT_SPEED);
|
uart_flush_input (sp);
|
||||||
|
uart_set_speed (sp, ACR122S_DEFAULT_SPEED);
|
||||||
|
|
||||||
nfc_device_t *dev = nfc_device_new();
|
nfc_connstring connstring;
|
||||||
dev->driver = &acr122s_driver;
|
snprintf (connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, ACR122S_DRIVER_NAME, acPort, ACR122S_DEFAULT_SPEED);
|
||||||
|
nfc_device *pnd = nfc_device_new (connstring);
|
||||||
|
|
||||||
dev->driver_data = malloc(sizeof(struct acr122s_data));
|
pnd->driver = &acr122s_driver;
|
||||||
DRIVER_DATA(dev)->port = sp;
|
pnd->driver_data = malloc(sizeof(struct acr122s_data));
|
||||||
DRIVER_DATA(dev)->seq = 0;
|
DRIVER_DATA (pnd)->port = sp;
|
||||||
|
DRIVER_DATA(pnd)->seq = 0;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
pipe(DRIVER_DATA(dev)->abort_fds);
|
pipe(DRIVER_DATA(pnd)->abort_fds);
|
||||||
#else
|
#else
|
||||||
DRIVER_DATA(dev)->abort_flag = false;
|
DRIVER_DATA(pnd)->abort_flag = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pn53x_data_new(dev, &acr122s_io);
|
pn53x_data_new(pnd, &acr122s_io);
|
||||||
CHIP_DATA(dev)->type = PN532;
|
CHIP_DATA(pnd)->type = PN532;
|
||||||
CHIP_DATA(dev)->power_mode = NORMAL;
|
CHIP_DATA(pnd)->power_mode = NORMAL;
|
||||||
|
|
||||||
char version[32];
|
char version[32];
|
||||||
int ret = acr122s_get_firmware_version(dev, version, sizeof(version));
|
int ret = acr122s_get_firmware_version(pnd, version, sizeof(version));
|
||||||
if (ret == 0 && strncmp("ACR122S", version, 7) != 0) {
|
if (ret == 0 && strncmp("ACR122S", version, 7) != 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pn53x_data_free(dev);
|
pn53x_data_free(pnd);
|
||||||
nfc_device_free(dev);
|
nfc_device_free(pnd);
|
||||||
uart_close(sp);
|
uart_close(sp);
|
||||||
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
nfc_device_desc_t *desc = &descs[(*dev_found)++];
|
// ACR122S reader is found
|
||||||
snprintf(desc->acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", ACR122S_DRIVER_NAME, port);
|
memcpy (connstrings[*pszDeviceFound], connstring, sizeof(nfc_connstring));
|
||||||
desc->pcDriver = ACR122S_DRIVER_NAME;
|
(*pszDeviceFound)++;
|
||||||
strncpy(desc->acPort, port, DEVICE_PORT_LENGTH - 1);
|
|
||||||
desc->acPort[DEVICE_PORT_LENGTH - 1] = '\0';
|
|
||||||
desc->uiSpeed = ACR122S_DEFAULT_SPEED;
|
|
||||||
|
|
||||||
// Test if we reach the maximum "wanted" devices
|
// Test if we reach the maximum "wanted" devices
|
||||||
if (*dev_found >= desc_count)
|
if (*pszDeviceFound >= connstrings_len)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
iDevice = 0;
|
||||||
for (int i = 0; ports[i]; i++)
|
while ((acPort = acPorts[iDevice++])) {
|
||||||
free(ports[i]);
|
free ((void*)acPort);
|
||||||
free(ports);
|
}
|
||||||
|
free (acPorts);
|
||||||
return true;
|
|
||||||
#endif /* SERIAL_AUTOPROBE_ENABLED */
|
#endif /* SERIAL_AUTOPROBE_ENABLED */
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_device_t *
|
nfc_device *
|
||||||
acr122s_connect(const nfc_device_desc_t *desc)
|
acr122s_open(const nfc_connstring connstring)
|
||||||
{
|
{
|
||||||
serial_port sp;
|
serial_port sp;
|
||||||
nfc_device_t *dev;
|
nfc_device *pnd;
|
||||||
|
struct acr122s_descriptor ndd;
|
||||||
|
int connstring_decode_level = acr122s_connstring_decode (connstring, &ndd);
|
||||||
|
|
||||||
|
if (connstring_decode_level < 2) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (connstring_decode_level < 3) {
|
||||||
|
ndd.speed = ACR122S_DEFAULT_SPEED;
|
||||||
|
}
|
||||||
|
|
||||||
log_put(LOG_CATEGORY, NFC_PRIORITY_TRACE,
|
log_put(LOG_CATEGORY, NFC_PRIORITY_TRACE,
|
||||||
"Attempt to connect to: %s at %d bauds.", desc->acPort, desc->uiSpeed);
|
"Attempt to connect to: %s at %d bauds.", ndd.port, ndd.speed);
|
||||||
|
|
||||||
sp = uart_open(desc->acPort);
|
sp = uart_open(ndd.port);
|
||||||
if (sp == INVALID_SERIAL_PORT) {
|
if (sp == INVALID_SERIAL_PORT) {
|
||||||
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR,
|
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR,
|
||||||
"Invalid serial port: %s", desc->acPort);
|
"Invalid serial port: %s", ndd.port);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (sp == CLAIMED_SERIAL_PORT) {
|
if (sp == CLAIMED_SERIAL_PORT) {
|
||||||
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR,
|
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR,
|
||||||
"Serial port already claimed: %s", desc->acPort);
|
"Serial port already claimed: %s", ndd.port);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uart_flush_input(sp);
|
uart_flush_input(sp);
|
||||||
uart_set_speed(sp, desc->uiSpeed);
|
uart_set_speed(sp, ndd.speed);
|
||||||
|
|
||||||
dev = nfc_device_new();
|
pnd = nfc_device_new(connstring);
|
||||||
dev->driver = &acr122s_driver;
|
pnd->driver = &acr122s_driver;
|
||||||
strcpy(dev->acName, ACR122S_DRIVER_NAME);
|
strcpy(pnd->name, ACR122S_DRIVER_NAME);
|
||||||
|
|
||||||
dev->driver_data = malloc(sizeof(struct acr122s_data));
|
pnd->driver_data = malloc(sizeof(struct acr122s_data));
|
||||||
DRIVER_DATA(dev)->port = sp;
|
DRIVER_DATA(pnd)->port = sp;
|
||||||
DRIVER_DATA(dev)->seq = 0;
|
DRIVER_DATA(pnd)->seq = 0;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
pipe(DRIVER_DATA(dev)->abort_fds);
|
pipe(DRIVER_DATA(pnd)->abort_fds);
|
||||||
#else
|
#else
|
||||||
DRIVER_DATA(dev)->abort_flag = false;
|
DRIVER_DATA(pnd)->abort_flag = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pn53x_data_new(dev, &acr122s_io);
|
pn53x_data_new(pnd, &acr122s_io);
|
||||||
CHIP_DATA(dev)->type = PN532;
|
CHIP_DATA(pnd)->type = PN532;
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// Retrieve firmware version
|
// Retrieve firmware version
|
||||||
char version[DEVICE_NAME_LENGTH];
|
char version[DEVICE_NAME_LENGTH];
|
||||||
if (acr122s_get_firmware_version(dev, version, sizeof(version)) != 0) {
|
if (acr122s_get_firmware_version(pnd, version, sizeof(version)) != 0) {
|
||||||
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Cannot get reader firmware.");
|
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Cannot get reader firmware.");
|
||||||
acr122s_disconnect(dev);
|
acr122s_close(pnd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp(version, "ACR122S", 7) != 0) {
|
if (strncmp(version, "ACR122S", 7) != 0) {
|
||||||
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "Invalid firmware version: %s",
|
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "Invalid firmware version: %s",
|
||||||
version);
|
version);
|
||||||
acr122s_disconnect(dev);
|
acr122s_close(pnd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(dev->acName, sizeof(dev->acName), "%s", version);
|
snprintf(pnd->name, sizeof(pnd->name), "%s", version);
|
||||||
|
|
||||||
// Activate SAM before operating
|
// Activate SAM before operating
|
||||||
if (acr122s_activate_sam(dev) != 0) {
|
if (acr122s_activate_sam(pnd) != 0) {
|
||||||
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Cannot activate SAM.");
|
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Cannot activate SAM.");
|
||||||
acr122s_disconnect(dev);
|
acr122s_close(pnd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!pn53x_init(dev)) {
|
if (!pn53x_init(pnd)) {
|
||||||
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Failed initializing PN532 chip.");
|
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Failed initializing PN532 chip.");
|
||||||
acr122s_disconnect(dev);
|
acr122s_close(pnd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dev;
|
return pnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
acr122s_disconnect (nfc_device_t *dev)
|
acr122s_close (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
acr122s_deactivate_sam(dev);
|
acr122s_deactivate_sam(pnd);
|
||||||
uart_close(DRIVER_DATA(dev)->port);
|
uart_close(DRIVER_DATA(pnd)->port);
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
// Release file descriptors used for abort mecanism
|
// Release file descriptors used for abort mecanism
|
||||||
close (DRIVER_DATA(dev)->abort_fds[0]);
|
close (DRIVER_DATA(pnd)->abort_fds[0]);
|
||||||
close (DRIVER_DATA(dev)->abort_fds[1]);
|
close (DRIVER_DATA(pnd)->abort_fds[1]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pn53x_data_free(dev);
|
pn53x_data_free(pnd);
|
||||||
nfc_device_free(dev);
|
nfc_device_free(pnd);
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
acr122s_send(nfc_device_t *dev, const byte_t *buf, const size_t buf_len, struct timeval *timeout)
|
|
||||||
{
|
|
||||||
uart_flush_input(DRIVER_DATA(dev)->port);
|
|
||||||
|
|
||||||
byte_t cmd[MAX_FRAME_SIZE];
|
|
||||||
acr122s_build_frame(dev, cmd, sizeof(cmd), 0, 0, buf, buf_len, 1);
|
|
||||||
int ret;
|
|
||||||
if ((ret = acr122s_send_frame(dev, cmd, timeout)) != 0) {
|
|
||||||
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
|
|
||||||
dev->iLastError = ret;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
acr122s_receive(nfc_device_t *dev, byte_t *buf, size_t buf_len, struct timeval *timeout)
|
acr122s_send(nfc_device *pnd, const uint8_t *buf, const size_t buf_len, int timeout)
|
||||||
|
{
|
||||||
|
uart_flush_input(DRIVER_DATA(pnd)->port);
|
||||||
|
|
||||||
|
uint8_t cmd[MAX_FRAME_SIZE];
|
||||||
|
acr122s_build_frame(pnd, cmd, sizeof(cmd), 0, 0, buf, buf_len, 1);
|
||||||
|
int ret;
|
||||||
|
if ((ret = acr122s_send_frame(pnd, cmd, timeout)) != 0) {
|
||||||
|
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
|
||||||
|
pnd->last_error = ret;
|
||||||
|
return pnd->last_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NFC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
acr122s_receive(nfc_device *pnd, uint8_t *buf, size_t buf_len, int timeout)
|
||||||
{
|
{
|
||||||
void *abort_p;
|
void *abort_p;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
abort_p = &(DRIVER_DATA(dev)->abort_fds[1]);
|
abort_p = &(DRIVER_DATA(pnd)->abort_fds[1]);
|
||||||
#else
|
#else
|
||||||
abort_p = &(DRIVER_DATA(dev)->abort_flag);
|
abort_p = &(DRIVER_DATA(pnd)->abort_flag);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
byte_t tmp[MAX_FRAME_SIZE];
|
uint8_t tmp[MAX_FRAME_SIZE];
|
||||||
dev->iLastError = acr122s_recv_frame(dev, tmp, sizeof(tmp), abort_p, timeout);
|
pnd->last_error = acr122s_recv_frame(pnd, tmp, sizeof(tmp), abort_p, timeout);
|
||||||
|
|
||||||
if (abort_p && (EOPABORT == dev->iLastError))
|
if (abort_p && (NFC_EOPABORTED == pnd->last_error)) {
|
||||||
return -1;
|
pnd->last_error = NFC_EOPABORTED;
|
||||||
|
return pnd->last_error;
|
||||||
|
}
|
||||||
|
|
||||||
if (dev->iLastError != 0) {
|
if (pnd->last_error < 0) {
|
||||||
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -612,27 +690,27 @@ acr122s_receive(nfc_device_t *dev, byte_t *buf, size_t buf_len, struct timeval *
|
||||||
size_t data_len = FRAME_SIZE(tmp) - 17;
|
size_t data_len = FRAME_SIZE(tmp) - 17;
|
||||||
if (data_len > buf_len) {
|
if (data_len > buf_len) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Receive buffer too small. (buf_len: %zu, data_len: %zu)", buf_len, data_len);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Receive buffer too small. (buf_len: %zu, data_len: %zu)", buf_len, data_len);
|
||||||
dev->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buf, tmp + 13, data_len);
|
memcpy(buf, tmp + 13, data_len);
|
||||||
return data_len;
|
return data_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int
|
||||||
acr122s_abort_command(nfc_device_t *dev)
|
acr122s_abort_command(nfc_device *pnd)
|
||||||
{
|
{
|
||||||
if (dev) {
|
if (pnd) {
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
close(DRIVER_DATA(dev)->abort_fds[0]);
|
close(DRIVER_DATA(pnd)->abort_fds[0]);
|
||||||
close(DRIVER_DATA(dev)->abort_fds[1]);
|
close(DRIVER_DATA(pnd)->abort_fds[1]);
|
||||||
pipe(DRIVER_DATA(dev)->abort_fds);
|
pipe(DRIVER_DATA(pnd)->abort_fds);
|
||||||
#else
|
#else
|
||||||
DRIVER_DATA(dev)->abort_flag = true;
|
DRIVER_DATA(pnd)->abort_flag = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return true;
|
return NFC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct pn53x_io acr122s_io = {
|
const struct pn53x_io acr122s_io = {
|
||||||
|
@ -640,11 +718,11 @@ const struct pn53x_io acr122s_io = {
|
||||||
.receive = acr122s_receive,
|
.receive = acr122s_receive,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct nfc_driver_t acr122s_driver = {
|
const struct nfc_driver acr122s_driver = {
|
||||||
.name = ACR122S_DRIVER_NAME,
|
.name = ACR122S_DRIVER_NAME,
|
||||||
.probe = acr122s_probe,
|
.probe = acr122s_probe,
|
||||||
.connect = acr122s_connect,
|
.open = acr122s_open,
|
||||||
.disconnect = acr122s_disconnect,
|
.close = acr122s_close,
|
||||||
.strerror = pn53x_strerror,
|
.strerror = pn53x_strerror,
|
||||||
|
|
||||||
.initiator_init = pn53x_initiator_init,
|
.initiator_init = pn53x_initiator_init,
|
||||||
|
@ -663,7 +741,8 @@ const struct nfc_driver_t acr122s_driver = {
|
||||||
.target_send_bits = pn53x_target_send_bits,
|
.target_send_bits = pn53x_target_send_bits,
|
||||||
.target_receive_bits = pn53x_target_receive_bits,
|
.target_receive_bits = pn53x_target_receive_bits,
|
||||||
|
|
||||||
.configure = pn53x_configure,
|
.device_set_property_bool = pn53x_set_property_bool,
|
||||||
|
.device_set_property_int = pn53x_set_property_int,
|
||||||
|
|
||||||
.abort_command = acr122s_abort_command,
|
.abort_command = acr122s_abort_command,
|
||||||
.idle = NULL,
|
.idle = NULL,
|
||||||
|
|
|
@ -28,14 +28,14 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <nfc/nfc-types.h>
|
#include <nfc/nfc-types.h>
|
||||||
|
|
||||||
bool acr122s_probe(nfc_device_desc_t descs[], size_t desc_count, size_t *dev_found);
|
bool acr122s_probe(nfc_connstring connstrings[], size_t connstrings_len, size_t *pszDeviceFound);
|
||||||
|
|
||||||
nfc_device_t *acr122s_connect(const nfc_device_desc_t *desc);
|
nfc_device *acr122s_open(const nfc_connstring connstring);
|
||||||
void acr122s_disconnect(nfc_device_t *dev);
|
void acr122s_close(nfc_device *pnd);
|
||||||
|
|
||||||
bool acr122s_send(nfc_device_t *dev, const byte_t *buf, size_t buf_len, struct timeval *timeout);
|
int acr122s_send(nfc_device *pnd, const uint8_t *buf, size_t buf_len, int timeout);
|
||||||
int acr122s_receive(nfc_device_t *dev, byte_t *buf, size_t buf_len, struct timeval *timeout);
|
int acr122s_receive(nfc_device *pnd, uint8_t *buf, size_t buf_len, int timeout);
|
||||||
|
|
||||||
extern const struct nfc_driver_t acr122s_driver;
|
extern const struct nfc_driver acr122s_driver;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
* This driver can handle ARYGON readers that use UART as bus.
|
* This driver can handle ARYGON readers that use UART as bus.
|
||||||
* UART connection can be direct (host<->arygon_uc) or could be provided by internal USB to serial interface (e.g. host<->ftdi_chip<->arygon_uc)
|
* UART connection can be direct (host<->arygon_uc) or could be provided by internal USB to serial interface (e.g. host<->ftdi_chip<->arygon_uc)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* vim: set ts=2 sw=2 et: */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif // HAVE_CONFIG_H
|
#endif // HAVE_CONFIG_H
|
||||||
|
@ -33,6 +36,7 @@
|
||||||
#include "arygon.h"
|
#include "arygon.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -64,7 +68,7 @@
|
||||||
#define DEV_ARYGON_PROTOCOL_TAMA_WAB '3'
|
#define DEV_ARYGON_PROTOCOL_TAMA_WAB '3'
|
||||||
|
|
||||||
#define ARYGON_DEFAULT_SPEED 9600
|
#define ARYGON_DEFAULT_SPEED 9600
|
||||||
#define ARYGON_DRIVER_NAME "ARYGON"
|
#define ARYGON_DRIVER_NAME "arygon"
|
||||||
#define LOG_CATEGORY "libnfc.driver.arygon"
|
#define LOG_CATEGORY "libnfc.driver.arygon"
|
||||||
|
|
||||||
#define DRIVER_DATA(pnd) ((struct arygon_data*)(pnd->driver_data))
|
#define DRIVER_DATA(pnd) ((struct arygon_data*)(pnd->driver_data))
|
||||||
|
@ -80,24 +84,24 @@ struct arygon_data {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const byte_t arygon_error_none[] = "FF000000\x0d\x0a";
|
static const uint8_t arygon_error_none[] = "FF000000\x0d\x0a";
|
||||||
static const byte_t arygon_error_incomplete_command[] = "FF0C0000\x0d\x0a";
|
static const uint8_t arygon_error_incomplete_command[] = "FF0C0000\x0d\x0a";
|
||||||
static const byte_t arygon_error_unknown_mode[] = "FF060000\x0d\x0a";
|
static const uint8_t arygon_error_unknown_mode[] = "FF060000\x0d\x0a";
|
||||||
|
|
||||||
bool arygon_reset_tama (nfc_device_t * pnd);
|
int arygon_reset_tama (nfc_device *pnd);
|
||||||
void arygon_firmware (nfc_device_t * pnd, char * str);
|
void arygon_firmware (nfc_device *pnd, char *str);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
|
arygon_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t *pszDeviceFound)
|
||||||
{
|
{
|
||||||
/** @note: Due to UART bus we can't know if its really an ARYGON without
|
/** @note: Due to UART bus we can't know if its really an ARYGON without
|
||||||
* sending some commands. But using this way to probe devices, we can
|
* sending some commands. But using this way to probe devices, we can
|
||||||
* have serious problem with other device on this bus */
|
* have serious problem with other device on this bus */
|
||||||
#ifndef SERIAL_AUTOPROBE_ENABLED
|
#ifndef SERIAL_AUTOPROBE_ENABLED
|
||||||
(void) pnddDevices;
|
(void) connstrings;
|
||||||
(void) szDevices;
|
(void) connstrings_len;
|
||||||
*pszDeviceFound = 0;
|
*pszDeviceFound = 0;
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%s", "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_INFO, "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
|
||||||
return false;
|
return false;
|
||||||
#else /* SERIAL_AUTOPROBE_ENABLED */
|
#else /* SERIAL_AUTOPROBE_ENABLED */
|
||||||
*pszDeviceFound = 0;
|
*pszDeviceFound = 0;
|
||||||
|
@ -116,7 +120,10 @@ arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
|
||||||
uart_flush_input (sp);
|
uart_flush_input (sp);
|
||||||
uart_set_speed (sp, ARYGON_DEFAULT_SPEED);
|
uart_set_speed (sp, ARYGON_DEFAULT_SPEED);
|
||||||
|
|
||||||
nfc_device_t *pnd = nfc_device_new ();
|
nfc_connstring connstring;
|
||||||
|
snprintf (connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, ARYGON_DRIVER_NAME, acPort, ARYGON_DEFAULT_SPEED);
|
||||||
|
nfc_device *pnd = nfc_device_new (connstring);
|
||||||
|
|
||||||
pnd->driver = &arygon_driver;
|
pnd->driver = &arygon_driver;
|
||||||
pnd->driver_data = malloc(sizeof(struct arygon_data));
|
pnd->driver_data = malloc(sizeof(struct arygon_data));
|
||||||
DRIVER_DATA (pnd)->port = sp;
|
DRIVER_DATA (pnd)->port = sp;
|
||||||
|
@ -131,28 +138,22 @@ arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
|
||||||
DRIVER_DATA (pnd)->abort_flag = false;
|
DRIVER_DATA (pnd)->abort_flag = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool res = arygon_reset_tama (pnd);
|
int res = arygon_reset_tama (pnd);
|
||||||
pn53x_data_free (pnd);
|
pn53x_data_free (pnd);
|
||||||
nfc_device_free (pnd);
|
nfc_device_free (pnd);
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
if(!res)
|
if(res < 0) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// ARYGON reader is found
|
// ARYGON reader is found
|
||||||
snprintf (pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "Arygon", acPort);
|
memcpy (connstrings[*pszDeviceFound], connstring, sizeof(nfc_connstring));
|
||||||
pnddDevices[*pszDeviceFound].pcDriver = ARYGON_DRIVER_NAME;
|
|
||||||
strncpy (pnddDevices[*pszDeviceFound].acPort, acPort, DEVICE_PORT_LENGTH - 1); pnddDevices[*pszDeviceFound].acPort[DEVICE_PORT_LENGTH - 1] = '\0';
|
|
||||||
pnddDevices[*pszDeviceFound].uiSpeed = ARYGON_DEFAULT_SPEED;
|
|
||||||
(*pszDeviceFound)++;
|
(*pszDeviceFound)++;
|
||||||
|
|
||||||
// Test if we reach the maximum "wanted" devices
|
// Test if we reach the maximum "wanted" devices
|
||||||
if ((*pszDeviceFound) >= szDevices)
|
if ((*pszDeviceFound) >= connstrings_len)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (sp == INVALID_SERIAL_PORT)
|
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Invalid serial port: %s", acPort);
|
|
||||||
if (sp == CLAIMED_SERIAL_PORT)
|
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Serial port already claimed: %s", acPort);
|
|
||||||
}
|
}
|
||||||
iDevice = 0;
|
iDevice = 0;
|
||||||
while ((acPort = acPorts[iDevice++])) {
|
while ((acPort = acPorts[iDevice++])) {
|
||||||
|
@ -163,37 +164,100 @@ arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_device_t *
|
struct arygon_descriptor {
|
||||||
arygon_connect (const nfc_device_desc_t * pndd)
|
char port[128];
|
||||||
{
|
uint32_t speed;
|
||||||
serial_port sp;
|
};
|
||||||
nfc_device_t *pnd = NULL;
|
|
||||||
|
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to connect to: %s at %d bauds.", pndd->acPort, pndd->uiSpeed);
|
int
|
||||||
sp = uart_open (pndd->acPort);
|
arygon_connstring_decode (const nfc_connstring connstring, struct arygon_descriptor *desc)
|
||||||
|
{
|
||||||
|
char *cs = malloc (strlen (connstring) + 1);
|
||||||
|
if (!cs) {
|
||||||
|
perror ("malloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy (cs, connstring);
|
||||||
|
const char *driver_name = strtok (cs, ":");
|
||||||
|
if (!driver_name) {
|
||||||
|
// Parse error
|
||||||
|
free (cs);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != strcmp (driver_name, ARYGON_DRIVER_NAME)) {
|
||||||
|
// Driver name does not match.
|
||||||
|
free (cs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *port = strtok (NULL, ":");
|
||||||
|
if (!port) {
|
||||||
|
// Only driver name was specified (or parsing error)
|
||||||
|
free (cs);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strncpy (desc->port, port, sizeof(desc->port)-1);
|
||||||
|
desc->port[sizeof(desc->port)-1] = '\0';
|
||||||
|
|
||||||
|
const char *speed_s = strtok (NULL, ":");
|
||||||
|
if (!speed_s) {
|
||||||
|
// speed not specified (or parsing error)
|
||||||
|
free (cs);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
unsigned long speed;
|
||||||
|
if (sscanf (speed_s, "%lu", &speed) != 1) {
|
||||||
|
// speed_s is not a number
|
||||||
|
free (cs);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
desc->speed = speed;
|
||||||
|
|
||||||
|
free (cs);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
nfc_device *
|
||||||
|
arygon_open (const nfc_connstring connstring)
|
||||||
|
{
|
||||||
|
struct arygon_descriptor ndd;
|
||||||
|
int connstring_decode_level = arygon_connstring_decode (connstring, &ndd);
|
||||||
|
|
||||||
|
if (connstring_decode_level < 2) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (connstring_decode_level < 3) {
|
||||||
|
ndd.speed = ARYGON_DEFAULT_SPEED;
|
||||||
|
}
|
||||||
|
serial_port sp;
|
||||||
|
nfc_device *pnd = NULL;
|
||||||
|
|
||||||
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to open: %s at %d bauds.", ndd.port, ndd.speed);
|
||||||
|
sp = uart_open (ndd.port);
|
||||||
|
|
||||||
if (sp == INVALID_SERIAL_PORT)
|
if (sp == INVALID_SERIAL_PORT)
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Invalid serial port: %s", pndd->acPort);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Invalid serial port: %s", ndd.port);
|
||||||
if (sp == CLAIMED_SERIAL_PORT)
|
if (sp == CLAIMED_SERIAL_PORT)
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Serial port already claimed: %s", pndd->acPort);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Serial port already claimed: %s", ndd.port);
|
||||||
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
|
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// We need to flush input to be sure first reply does not comes from older byte transceive
|
// We need to flush input to be sure first reply does not comes from older byte transceive
|
||||||
uart_flush_input (sp);
|
uart_flush_input (sp);
|
||||||
uart_set_speed (sp, pndd->uiSpeed);
|
uart_set_speed (sp, ndd.speed);
|
||||||
|
|
||||||
// We have a connection
|
// We have a connection
|
||||||
pnd = nfc_device_new ();
|
pnd = nfc_device_new (connstring);
|
||||||
strncpy (pnd->acName, pndd->acDevice, sizeof (pnd->acName));
|
snprintf (pnd->name, sizeof (pnd->name), "%s:%s", ARYGON_DRIVER_NAME, ndd.port);
|
||||||
|
|
||||||
pnd->driver_data = malloc(sizeof(struct arygon_data));
|
pnd->driver_data = malloc(sizeof(struct arygon_data));
|
||||||
DRIVER_DATA (pnd)->port = sp;
|
DRIVER_DATA (pnd)->port = sp;
|
||||||
|
|
||||||
// Alloc and init chip's data
|
// Alloc and init chip's data
|
||||||
pn53x_data_new (pnd, &arygon_tama_io);
|
pn53x_data_new (pnd, &arygon_tama_io);
|
||||||
|
|
||||||
// The PN53x chip connected to ARYGON MCU doesn't seems to be in LowVBat mode
|
// The PN53x chip opened to ARYGON MCU doesn't seems to be in LowVBat mode
|
||||||
CHIP_DATA (pnd)->power_mode = NORMAL;
|
CHIP_DATA (pnd)->power_mode = NORMAL;
|
||||||
|
|
||||||
// empirical tuning
|
// empirical tuning
|
||||||
|
@ -208,16 +272,16 @@ arygon_connect (const nfc_device_desc_t * pndd)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check communication using "Reset TAMA" command
|
// Check communication using "Reset TAMA" command
|
||||||
if (!arygon_reset_tama(pnd)) {
|
if (arygon_reset_tama(pnd) < 0) {
|
||||||
nfc_device_free (pnd);
|
arygon_close (pnd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char arygon_firmware_version[10];
|
char arygon_firmware_version[10];
|
||||||
arygon_firmware (pnd, arygon_firmware_version);
|
arygon_firmware (pnd, arygon_firmware_version);
|
||||||
char *pcName;
|
char *pcName;
|
||||||
pcName = strdup (pnd->acName);
|
pcName = strdup (pnd->name);
|
||||||
snprintf (pnd->acName, sizeof (pnd->acName), "%s %s", pcName, arygon_firmware_version);
|
snprintf (pnd->name, sizeof (pnd->name), "%s %s", pcName, arygon_firmware_version);
|
||||||
free (pcName);
|
free (pcName);
|
||||||
|
|
||||||
pn53x_init(pnd);
|
pn53x_init(pnd);
|
||||||
|
@ -225,7 +289,7 @@ arygon_connect (const nfc_device_desc_t * pndd)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
arygon_disconnect (nfc_device_t * pnd)
|
arygon_close (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
// Release UART port
|
// Release UART port
|
||||||
uart_close (DRIVER_DATA (pnd)->port);
|
uart_close (DRIVER_DATA (pnd)->port);
|
||||||
|
@ -242,109 +306,108 @@ arygon_disconnect (nfc_device_t * pnd)
|
||||||
|
|
||||||
#define ARYGON_TX_BUFFER_LEN (PN53x_NORMAL_FRAME__DATA_MAX_LEN + PN53x_NORMAL_FRAME__OVERHEAD + 1)
|
#define ARYGON_TX_BUFFER_LEN (PN53x_NORMAL_FRAME__DATA_MAX_LEN + PN53x_NORMAL_FRAME__OVERHEAD + 1)
|
||||||
#define ARYGON_RX_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
|
#define ARYGON_RX_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
|
||||||
bool
|
int
|
||||||
arygon_tama_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout)
|
arygon_tama_send (nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout)
|
||||||
{
|
{
|
||||||
|
int res = 0;
|
||||||
// Before sending anything, we need to discard from any junk bytes
|
// Before sending anything, we need to discard from any junk bytes
|
||||||
uart_flush_input (DRIVER_DATA(pnd)->port);
|
uart_flush_input (DRIVER_DATA(pnd)->port);
|
||||||
|
|
||||||
byte_t abtFrame[ARYGON_TX_BUFFER_LEN] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "0x32 0x00 0x00 0xff"
|
uint8_t abtFrame[ARYGON_TX_BUFFER_LEN] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "0x32 0x00 0x00 0xff"
|
||||||
|
|
||||||
size_t szFrame = 0;
|
size_t szFrame = 0;
|
||||||
if (szData > PN53x_NORMAL_FRAME__DATA_MAX_LEN) {
|
if (szData > PN53x_NORMAL_FRAME__DATA_MAX_LEN) {
|
||||||
// ARYGON Reader with PN532 equipped does not support extended frame (bug in ARYGON firmware?)
|
// ARYGON Reader with PN532 equipped does not support extended frame (bug in ARYGON firmware?)
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "ARYGON device does not support more than %d bytes as payload (requested: %zd)", PN53x_NORMAL_FRAME__DATA_MAX_LEN, szData);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "ARYGON device does not support more than %d bytes as payload (requested: %zd)", PN53x_NORMAL_FRAME__DATA_MAX_LEN, szData);
|
||||||
pnd->iLastError = EDEVNOTSUP;
|
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pn53x_build_frame (abtFrame + 1, &szFrame, pbtData, szData)) {
|
if ((res = pn53x_build_frame (abtFrame + 1, &szFrame, pbtData, szData)) < 0) {
|
||||||
pnd->iLastError = EINVALARG;
|
pnd->last_error = res;
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = uart_send (DRIVER_DATA (pnd)->port, abtFrame, szFrame + 1, timeout);
|
if ((res = uart_send (DRIVER_DATA (pnd)->port, abtFrame, szFrame + 1, timeout)) != 0) {
|
||||||
if (res != 0) {
|
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
|
||||||
pnd->iLastError = res;
|
pnd->last_error = res;
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_t abtRxBuf[6];
|
uint8_t abtRxBuf[6];
|
||||||
res = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, sizeof (abtRxBuf), 0, timeout);
|
if ((res = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, sizeof (abtRxBuf), 0, timeout)) != 0) {
|
||||||
if (res != 0) {
|
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to read ACK");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to read ACK");
|
||||||
pnd->iLastError = res;
|
pnd->last_error = res;
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pn53x_check_ack_frame (pnd, abtRxBuf, sizeof(abtRxBuf))) {
|
if (pn53x_check_ack_frame (pnd, abtRxBuf, sizeof(abtRxBuf)) == 0) {
|
||||||
// The PN53x is running the sent command
|
// The PN53x is running the sent command
|
||||||
} else if (0 == memcmp(arygon_error_unknown_mode, abtRxBuf, sizeof(abtRxBuf))) {
|
} else if (0 == memcmp(arygon_error_unknown_mode, abtRxBuf, sizeof(abtRxBuf))) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Bad frame format." );
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Bad frame format." );
|
||||||
// We have already read 6 bytes and arygon_error_unknown_mode is 10 bytes long
|
// We have already read 6 bytes and arygon_error_unknown_mode is 10 bytes long
|
||||||
// so we have to read 4 remaining bytes to be synchronized at the next receiving pass.
|
// so we have to read 4 remaining bytes to be synchronized at the next receiving pass.
|
||||||
uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 4, 0, timeout);
|
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 4, 0, timeout);
|
||||||
return false;
|
return pnd->last_error;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
return true;
|
return NFC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
arygon_abort (nfc_device_t *pnd)
|
arygon_abort (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
// Send a valid TAMA packet to wakup the PN53x (we will not have an answer, according to Arygon manual)
|
// Send a valid TAMA packet to wakup the PN53x (we will not have an answer, according to Arygon manual)
|
||||||
byte_t dummy[] = { 0x32, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 0x6c, 0x69, 0x62, 0x6e, 0x66, 0x63, 0xbe, 0x00 };
|
uint8_t dummy[] = { 0x32, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 0x6c, 0x69, 0x62, 0x6e, 0x66, 0x63, 0xbe, 0x00 };
|
||||||
|
|
||||||
uart_send (DRIVER_DATA (pnd)->port, dummy, sizeof (dummy), NULL);
|
uart_send (DRIVER_DATA (pnd)->port, dummy, sizeof (dummy), 0);
|
||||||
|
|
||||||
// Using Arygon device we can't send ACK frame to abort the running command
|
// Using Arygon device we can't send ACK frame to abort the running command
|
||||||
return (pn53x_check_communication (pnd)) ? 0 : -1;
|
return pn53x_check_communication (pnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen, struct timeval *timeout)
|
arygon_tama_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, int timeout)
|
||||||
{
|
{
|
||||||
byte_t abtRxBuf[5];
|
uint8_t abtRxBuf[5];
|
||||||
size_t len;
|
size_t len;
|
||||||
void * abort_p = NULL;
|
void *abort_p = NULL;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
abort_p = &(DRIVER_DATA (pnd)->iAbortFds[1]);
|
abort_p = &(DRIVER_DATA (pnd)->iAbortFds[1]);
|
||||||
#else
|
#else
|
||||||
abort_p = &(DRIVER_DATA (pnd)->abort_flag);
|
abort_p = (void*)&(DRIVER_DATA (pnd)->abort_flag);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pnd->iLastError = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 5, abort_p, timeout);
|
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 5, abort_p, timeout);
|
||||||
|
|
||||||
if (abort_p && (EOPABORT == pnd->iLastError)) {
|
if (abort_p && (NFC_EOPABORTED == pnd->last_error)) {
|
||||||
arygon_abort (pnd);
|
arygon_abort (pnd);
|
||||||
|
|
||||||
/* iLastError got reset by arygon_abort() */
|
/* last_error got reset by arygon_abort() */
|
||||||
pnd->iLastError = EOPABORT;
|
pnd->last_error = NFC_EOPABORTED;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pnd->iLastError != 0) {
|
if (pnd->last_error != 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
const byte_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
|
const uint8_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
|
||||||
if (0 != (memcmp (abtRxBuf, pn53x_preamble, 3))) {
|
if (0 != (memcmp (abtRxBuf, pn53x_preamble, 3))) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
|
if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
|
||||||
// Error frame
|
// Error frame
|
||||||
uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 3, 0, timeout);
|
uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 3, 0, timeout);
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Application level error detected");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Application level error detected");
|
||||||
pnd->iLastError = EFRAISERRFRAME;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
} else if ((0xff == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
|
} else if ((0xff == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
|
||||||
// Extended frame
|
// Extended frame
|
||||||
// ARYGON devices does not support extended frame sending
|
// ARYGON devices does not support extended frame sending
|
||||||
|
@ -354,8 +417,8 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
|
||||||
if (256 != (abtRxBuf[3] + abtRxBuf[4])) {
|
if (256 != (abtRxBuf[3] + abtRxBuf[4])) {
|
||||||
// TODO: Retry
|
// TODO: Retry
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// abtRxBuf[3] (LEN) include TFI + (CC+1)
|
// abtRxBuf[3] (LEN) include TFI + (CC+1)
|
||||||
|
@ -364,85 +427,85 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
|
||||||
|
|
||||||
if (len > szDataLen) {
|
if (len > szDataLen) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len);
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TFI + PD0 (CC+1)
|
// TFI + PD0 (CC+1)
|
||||||
pnd->iLastError = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
|
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
|
||||||
if (pnd->iLastError != 0) {
|
if (pnd->last_error != 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abtRxBuf[0] != 0xD5) {
|
if (abtRxBuf[0] != 0xD5) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "TFI Mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "TFI Mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abtRxBuf[1] != CHIP_DATA (pnd)->ui8LastCommand + 1) {
|
if (abtRxBuf[1] != CHIP_DATA (pnd)->last_command + 1) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Command Code verification failed");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Command Code verification failed");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
pnd->iLastError = uart_receive (DRIVER_DATA (pnd)->port, pbtData, len, 0, timeout);
|
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, pbtData, len, 0, timeout);
|
||||||
if (pnd->iLastError != 0) {
|
if (pnd->last_error != 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pnd->iLastError = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
|
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
|
||||||
if (pnd->iLastError != 0) {
|
if (pnd->last_error != 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_t btDCS = (256 - 0xD5);
|
uint8_t btDCS = (256 - 0xD5);
|
||||||
btDCS -= CHIP_DATA (pnd)->ui8LastCommand + 1;
|
btDCS -= CHIP_DATA (pnd)->last_command + 1;
|
||||||
for (size_t szPos = 0; szPos < len; szPos++) {
|
for (size_t szPos = 0; szPos < len; szPos++) {
|
||||||
btDCS -= pbtData[szPos];
|
btDCS -= pbtData[szPos];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (btDCS != abtRxBuf[0]) {
|
if (btDCS != abtRxBuf[0]) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Data checksum mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Data checksum mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0x00 != abtRxBuf[1]) {
|
if (0x00 != abtRxBuf[1]) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
// The PN53x command is done and we successfully received the reply
|
// The PN53x command is done and we successfully received the reply
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
arygon_firmware (nfc_device_t * pnd, char * str)
|
arygon_firmware (nfc_device *pnd, char *str)
|
||||||
{
|
{
|
||||||
const byte_t arygon_firmware_version_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'v' };
|
const uint8_t arygon_firmware_version_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'v' };
|
||||||
byte_t abtRx[16];
|
uint8_t abtRx[16];
|
||||||
size_t szRx = sizeof(abtRx);
|
size_t szRx = sizeof(abtRx);
|
||||||
|
|
||||||
|
|
||||||
int res = uart_send (DRIVER_DATA (pnd)->port, arygon_firmware_version_cmd, sizeof (arygon_firmware_version_cmd), NULL);
|
int res = uart_send (DRIVER_DATA (pnd)->port, arygon_firmware_version_cmd, sizeof (arygon_firmware_version_cmd), 0);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Unable to send ARYGON firmware command.");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Unable to send ARYGON firmware command.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
res = uart_receive (DRIVER_DATA (pnd)->port, abtRx, szRx, 0, NULL);
|
res = uart_receive (DRIVER_DATA (pnd)->port, abtRx, szRx, 0, 0);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Unable to retrieve ARYGON firmware version.");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Unable to retrieve ARYGON firmware version.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 0 == memcmp (abtRx, arygon_error_none, 6)) {
|
if ( 0 == memcmp (abtRx, arygon_error_none, 6)) {
|
||||||
byte_t * p = abtRx + 6;
|
uint8_t *p = abtRx + 6;
|
||||||
unsigned int szData;
|
unsigned int szData;
|
||||||
sscanf ((const char*)p, "%02x%s", &szData, p);
|
sscanf ((const char*)p, "%02x%s", &szData, p);
|
||||||
memcpy (str, p, szData);
|
memcpy (str, p, szData);
|
||||||
|
@ -450,37 +513,35 @@ arygon_firmware (nfc_device_t * pnd, char * str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int
|
||||||
arygon_reset_tama (nfc_device_t * pnd)
|
arygon_reset_tama (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
const byte_t arygon_reset_tama_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'r' };
|
const uint8_t arygon_reset_tama_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'r' };
|
||||||
byte_t abtRx[10]; // Attempted response is 10 bytes long
|
uint8_t abtRx[10]; // Attempted response is 10 bytes long
|
||||||
size_t szRx = sizeof(abtRx);
|
size_t szRx = sizeof(abtRx);
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
struct timeval tv;
|
uart_send (DRIVER_DATA (pnd)->port, arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd), 500);
|
||||||
tv.tv_sec = 1;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
|
|
||||||
uart_send (DRIVER_DATA (pnd)->port, arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd), &tv);
|
|
||||||
|
|
||||||
// Two reply are possible from ARYGON device: arygon_error_none (ie. in case the byte is well-sent)
|
// Two reply are possible from ARYGON device: arygon_error_none (ie. in case the byte is well-sent)
|
||||||
// or arygon_error_unknown_mode (ie. in case of the first byte was bad-transmitted)
|
// or arygon_error_unknown_mode (ie. in case of the first byte was bad-transmitted)
|
||||||
res = uart_receive (DRIVER_DATA (pnd)->port, abtRx, szRx, 0, &tv);
|
res = uart_receive (DRIVER_DATA (pnd)->port, abtRx, szRx, 0, 1000);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "No reply to 'reset TAMA' command.");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "No reply to 'reset TAMA' command.");
|
||||||
return false;
|
pnd->last_error = res;
|
||||||
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != memcmp (abtRx, arygon_error_none, sizeof (arygon_error_none) - 1)) {
|
if (0 != memcmp (abtRx, arygon_error_none, sizeof (arygon_error_none) - 1)) {
|
||||||
return false;
|
pnd->last_error = NFC_EIO;
|
||||||
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return NFC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int
|
||||||
arygon_abort_command (nfc_device_t * pnd)
|
arygon_abort_command (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
if (pnd) {
|
if (pnd) {
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
@ -490,7 +551,7 @@ arygon_abort_command (nfc_device_t * pnd)
|
||||||
DRIVER_DATA (pnd)->abort_flag = true;
|
DRIVER_DATA (pnd)->abort_flag = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return true;
|
return NFC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -499,12 +560,12 @@ const struct pn53x_io arygon_tama_io = {
|
||||||
.receive = arygon_tama_receive,
|
.receive = arygon_tama_receive,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct nfc_driver_t arygon_driver = {
|
const struct nfc_driver arygon_driver = {
|
||||||
.name = ARYGON_DRIVER_NAME,
|
.name = ARYGON_DRIVER_NAME,
|
||||||
.probe = arygon_probe,
|
.probe = arygon_probe,
|
||||||
.connect = arygon_connect,
|
.open = arygon_open,
|
||||||
.disconnect = arygon_disconnect,
|
.close = arygon_close,
|
||||||
.strerror = pn53x_strerror,
|
.strerror = pn53x_strerror,
|
||||||
|
|
||||||
.initiator_init = pn53x_initiator_init,
|
.initiator_init = pn53x_initiator_init,
|
||||||
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
||||||
|
@ -522,10 +583,10 @@ const struct nfc_driver_t arygon_driver = {
|
||||||
.target_send_bits = pn53x_target_send_bits,
|
.target_send_bits = pn53x_target_send_bits,
|
||||||
.target_receive_bits = pn53x_target_receive_bits,
|
.target_receive_bits = pn53x_target_receive_bits,
|
||||||
|
|
||||||
.configure = pn53x_configure,
|
.device_set_property_bool = pn53x_set_property_bool,
|
||||||
|
.device_set_property_int = pn53x_set_property_int,
|
||||||
|
|
||||||
.abort_command = arygon_abort_command,
|
.abort_command = arygon_abort_command,
|
||||||
// FIXME Implement me
|
.idle = NULL, // FIXME arygon driver does not support idle()
|
||||||
.idle = NULL,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,14 +30,14 @@
|
||||||
|
|
||||||
# include <nfc/nfc-types.h>
|
# include <nfc/nfc-types.h>
|
||||||
|
|
||||||
bool arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
|
bool arygon_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t *pszDeviceFound);
|
||||||
|
|
||||||
nfc_device_t *arygon_connect (const nfc_device_desc_t * pndd);
|
nfc_device *arygon_open (const nfc_connstring connstring);
|
||||||
void arygon_disconnect (nfc_device_t * pnd);
|
void arygon_close (nfc_device *pnd);
|
||||||
|
|
||||||
bool arygon_tama_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout);
|
int arygon_tama_send (nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout);
|
||||||
int arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDat, struct timeval *timeouta);
|
int arygon_tama_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szDat, int timeouta);
|
||||||
|
|
||||||
extern const struct nfc_driver_t arygon_driver;
|
extern const struct nfc_driver arygon_driver;
|
||||||
|
|
||||||
#endif // ! __NFC_DRIVER_ARYGON_H__
|
#endif // ! __NFC_DRIVER_ARYGON_H__
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "pn532_uart.h"
|
#include "pn532_uart.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -44,11 +45,11 @@
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
|
|
||||||
#define PN532_UART_DEFAULT_SPEED 115200
|
#define PN532_UART_DEFAULT_SPEED 115200
|
||||||
#define PN532_UART_DRIVER_NAME "PN532_UART"
|
#define PN532_UART_DRIVER_NAME "pn532_uart"
|
||||||
#define LOG_CATEGORY "libnfc.driver.pn532_uart"
|
#define LOG_CATEGORY "libnfc.driver.pn532_uart"
|
||||||
|
|
||||||
int pn532_uart_ack (nfc_device_t * pnd);
|
int pn532_uart_ack (nfc_device *pnd);
|
||||||
int pn532_uart_wakeup (nfc_device_t * pnd);
|
int pn532_uart_wakeup (nfc_device *pnd);
|
||||||
|
|
||||||
const struct pn53x_io pn532_uart_io;
|
const struct pn53x_io pn532_uart_io;
|
||||||
|
|
||||||
|
@ -64,14 +65,14 @@ struct pn532_uart_data {
|
||||||
#define DRIVER_DATA(pnd) ((struct pn532_uart_data*)(pnd->driver_data))
|
#define DRIVER_DATA(pnd) ((struct pn532_uart_data*)(pnd->driver_data))
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
|
pn532_uart_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t *pszDeviceFound)
|
||||||
{
|
{
|
||||||
/** @note: Due to UART bus we can't know if its really a pn532 without
|
/** @note: Due to UART bus we can't know if its really a pn532 without
|
||||||
* sending some PN53x commands. But using this way to probe devices, we can
|
* sending some PN53x commands. But using this way to probe devices, we can
|
||||||
* have serious problem with other device on this bus */
|
* have serious problem with other device on this bus */
|
||||||
#ifndef SERIAL_AUTOPROBE_ENABLED
|
#ifndef SERIAL_AUTOPROBE_ENABLED
|
||||||
(void) pnddDevices;
|
(void) connstrings;
|
||||||
(void) szDevices;
|
(void) connstrings_len;
|
||||||
*pszDeviceFound = 0;
|
*pszDeviceFound = 0;
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_INFO, "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_INFO, "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -90,10 +91,12 @@ pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps
|
||||||
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
|
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
|
// We need to flush input to be sure first reply does not comes from older byte transceive
|
||||||
uart_flush_input (sp);
|
uart_flush_input (sp);
|
||||||
// Serial port claimed but we need to check if a PN532_UART is connected.
|
// Serial port claimed but we need to check if a PN532_UART is opened.
|
||||||
uart_set_speed (sp, PN532_UART_DEFAULT_SPEED);
|
uart_set_speed (sp, PN532_UART_DEFAULT_SPEED);
|
||||||
|
|
||||||
nfc_device_t *pnd = nfc_device_new ();
|
nfc_connstring connstring;
|
||||||
|
snprintf (connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, PN532_UART_DRIVER_NAME, acPort, PN532_UART_DEFAULT_SPEED);
|
||||||
|
nfc_device *pnd = nfc_device_new (connstring);
|
||||||
pnd->driver = &pn532_uart_driver;
|
pnd->driver = &pn532_uart_driver;
|
||||||
pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
|
pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
|
||||||
DRIVER_DATA (pnd)->port = sp;
|
DRIVER_DATA (pnd)->port = sp;
|
||||||
|
@ -113,29 +116,22 @@ pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check communication using "Diagnose" command, with "Communication test" (0x00)
|
// Check communication using "Diagnose" command, with "Communication test" (0x00)
|
||||||
bool res = pn53x_check_communication (pnd);
|
int res = pn53x_check_communication (pnd);
|
||||||
if(!res) {
|
|
||||||
nfc_perror (pnd, "pn53x_check_communication");
|
|
||||||
}
|
|
||||||
pn53x_data_free (pnd);
|
pn53x_data_free (pnd);
|
||||||
nfc_device_free (pnd);
|
nfc_device_free (pnd);
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
if(!res) {
|
if(res < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf (pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "PN532", acPort);
|
memcpy (connstrings[*pszDeviceFound], connstring, sizeof (nfc_connstring));
|
||||||
pnddDevices[*pszDeviceFound].pcDriver = PN532_UART_DRIVER_NAME;
|
|
||||||
strncpy (pnddDevices[*pszDeviceFound].acPort, acPort, DEVICE_PORT_LENGTH - 1); pnddDevices[*pszDeviceFound].acPort[DEVICE_PORT_LENGTH - 1] = '\0';
|
|
||||||
pnddDevices[*pszDeviceFound].uiSpeed = PN532_UART_DEFAULT_SPEED;
|
|
||||||
(*pszDeviceFound)++;
|
(*pszDeviceFound)++;
|
||||||
|
|
||||||
// Test if we reach the maximum "wanted" devices
|
// Test if we reach the maximum "wanted" devices
|
||||||
if ((*pszDeviceFound) >= szDevices)
|
if ((*pszDeviceFound) >= connstrings_len)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iDevice = 0;
|
iDevice = 0;
|
||||||
while ((acPort = acPorts[iDevice++])) {
|
while ((acPort = acPorts[iDevice++])) {
|
||||||
free ((void*)acPort);
|
free ((void*)acPort);
|
||||||
|
@ -145,33 +141,96 @@ pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_device_t *
|
struct pn532_uart_descriptor {
|
||||||
pn532_uart_connect (const nfc_device_desc_t * pndd)
|
char port[128];
|
||||||
{
|
uint32_t speed;
|
||||||
serial_port sp;
|
};
|
||||||
nfc_device_t *pnd = NULL;
|
|
||||||
|
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to connect to: %s at %d bauds.", pndd->acPort, pndd->uiSpeed);
|
int
|
||||||
sp = uart_open (pndd->acPort);
|
pn532_connstring_decode (const nfc_connstring connstring, struct pn532_uart_descriptor *desc)
|
||||||
|
{
|
||||||
|
char *cs = malloc (strlen (connstring) + 1);
|
||||||
|
if (!cs) {
|
||||||
|
perror ("malloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy (cs, connstring);
|
||||||
|
const char *driver_name = strtok (cs, ":");
|
||||||
|
if (!driver_name) {
|
||||||
|
// Parse error
|
||||||
|
free (cs);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != strcmp (driver_name, PN532_UART_DRIVER_NAME)) {
|
||||||
|
// Driver name does not match.
|
||||||
|
free (cs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *port = strtok (NULL, ":");
|
||||||
|
if (!port) {
|
||||||
|
// Only driver name was specified (or parsing error)
|
||||||
|
free (cs);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strncpy (desc->port, port, sizeof(desc->port)-1);
|
||||||
|
desc->port[sizeof(desc->port)-1] = '\0';
|
||||||
|
|
||||||
|
const char *speed_s = strtok (NULL, ":");
|
||||||
|
if (!speed_s) {
|
||||||
|
// speed not specified (or parsing error)
|
||||||
|
free (cs);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
unsigned long speed;
|
||||||
|
if (sscanf (speed_s, "%lu", &speed) != 1) {
|
||||||
|
// speed_s is not a number
|
||||||
|
free (cs);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
desc->speed = speed;
|
||||||
|
|
||||||
|
free (cs);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
nfc_device *
|
||||||
|
pn532_uart_open (const nfc_connstring connstring)
|
||||||
|
{
|
||||||
|
struct pn532_uart_descriptor ndd;
|
||||||
|
int connstring_decode_level = pn532_connstring_decode (connstring, &ndd);
|
||||||
|
|
||||||
|
if (connstring_decode_level < 2) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (connstring_decode_level < 3) {
|
||||||
|
ndd.speed = PN532_UART_DEFAULT_SPEED;
|
||||||
|
}
|
||||||
|
serial_port sp;
|
||||||
|
nfc_device *pnd = NULL;
|
||||||
|
|
||||||
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to open: %s at %d bauds.", ndd.port, ndd.speed);
|
||||||
|
sp = uart_open (ndd.port);
|
||||||
|
|
||||||
if (sp == INVALID_SERIAL_PORT)
|
if (sp == INVALID_SERIAL_PORT)
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Invalid serial port: %s", pndd->acPort);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Invalid serial port: %s", ndd.port);
|
||||||
if (sp == CLAIMED_SERIAL_PORT)
|
if (sp == CLAIMED_SERIAL_PORT)
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Serial port already claimed: %s", pndd->acPort);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Serial port already claimed: %s", ndd.port);
|
||||||
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
|
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// We need to flush input to be sure first reply does not comes from older byte transceive
|
// We need to flush input to be sure first reply does not comes from older byte transceive
|
||||||
uart_flush_input (sp);
|
uart_flush_input (sp);
|
||||||
uart_set_speed (sp, pndd->uiSpeed);
|
uart_set_speed (sp, ndd.speed);
|
||||||
|
|
||||||
// We have a connection
|
// We have a connection
|
||||||
pnd = nfc_device_new ();
|
pnd = nfc_device_new (connstring);
|
||||||
strncpy (pnd->acName, pndd->acDevice, DEVICE_NAME_LENGTH - 1);
|
snprintf (pnd->name, sizeof (pnd->name), "%s:%s", PN532_UART_DRIVER_NAME, ndd.port);
|
||||||
pnd->acName[DEVICE_NAME_LENGTH - 1] = '\0';
|
|
||||||
|
|
||||||
pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
|
pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
|
||||||
DRIVER_DATA(pnd)->port = sp;
|
DRIVER_DATA (pnd)->port = sp;
|
||||||
|
|
||||||
// Alloc and init chip's data
|
// Alloc and init chip's data
|
||||||
pn53x_data_new (pnd, &pn532_uart_io);
|
pn53x_data_new (pnd, &pn532_uart_io);
|
||||||
// SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532
|
// SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532
|
||||||
|
@ -191,9 +250,9 @@ pn532_uart_connect (const nfc_device_desc_t * pndd)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check communication using "Diagnose" command, with "Communication test" (0x00)
|
// Check communication using "Diagnose" command, with "Communication test" (0x00)
|
||||||
if (!pn53x_check_communication (pnd)) {
|
if (pn53x_check_communication (pnd) < 0) {
|
||||||
nfc_perror (pnd, "pn53x_check_communication");
|
nfc_perror (pnd, "pn53x_check_communication");
|
||||||
pn532_uart_disconnect(pnd);
|
pn532_uart_close (pnd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +261,7 @@ pn532_uart_connect (const nfc_device_desc_t * pndd)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pn532_uart_disconnect (nfc_device_t * pnd)
|
pn532_uart_close (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
// Release UART port
|
// Release UART port
|
||||||
uart_close (DRIVER_DATA(pnd)->port);
|
uart_close (DRIVER_DATA(pnd)->port);
|
||||||
|
@ -218,40 +277,38 @@ pn532_uart_disconnect (nfc_device_t * pnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pn532_uart_wakeup (nfc_device_t * pnd)
|
pn532_uart_wakeup (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
/* High Speed Unit (HSU) wake up consist to send 0x55 and wait a "long" delay for PN532 being wakeup. */
|
/* High Speed Unit (HSU) wake up consist to send 0x55 and wait a "long" delay for PN532 being wakeup. */
|
||||||
const byte_t pn532_wakeup_preamble[] = { 0x55, 0x55, 0x00, 0x00, 0x00 };
|
const uint8_t pn532_wakeup_preamble[] = { 0x55, 0x55, 0x00, 0x00, 0x00 };
|
||||||
int res = uart_send (DRIVER_DATA(pnd)->port, pn532_wakeup_preamble, sizeof (pn532_wakeup_preamble), NULL);
|
int res = uart_send (DRIVER_DATA(pnd)->port, pn532_wakeup_preamble, sizeof (pn532_wakeup_preamble), 0);
|
||||||
CHIP_DATA(pnd)->power_mode = NORMAL; // PN532 should now be awake
|
CHIP_DATA(pnd)->power_mode = NORMAL; // PN532 should now be awake
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PN532_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
|
#define PN532_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
|
||||||
bool
|
int
|
||||||
pn532_uart_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout)
|
pn532_uart_send (nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout)
|
||||||
{
|
{
|
||||||
|
int res = 0;
|
||||||
// Before sending anything, we need to discard from any junk bytes
|
// Before sending anything, we need to discard from any junk bytes
|
||||||
uart_flush_input (DRIVER_DATA(pnd)->port);
|
uart_flush_input (DRIVER_DATA(pnd)->port);
|
||||||
|
|
||||||
switch (CHIP_DATA(pnd)->power_mode) {
|
switch (CHIP_DATA(pnd)->power_mode) {
|
||||||
case LOWVBAT: {
|
case LOWVBAT: {
|
||||||
/** PN532C106 wakeup. */
|
/** PN532C106 wakeup. */
|
||||||
if (-1 == pn532_uart_wakeup(pnd)) {
|
if ((res = pn532_uart_wakeup(pnd)) < 0) {
|
||||||
return false;
|
return res;
|
||||||
}
|
}
|
||||||
// According to PN532 application note, C106 appendix: to go out Low Vbat mode and enter in normal mode we need to send a SAMConfiguration command
|
// According to PN532 application note, C106 appendix: to go out Low Vbat mode and enter in normal mode we need to send a SAMConfiguration command
|
||||||
struct timeval tv;
|
if ((res = pn53x_SAMConfiguration (pnd, 0x01, 1000)) < 0) {
|
||||||
tv.tv_sec = 1;
|
return res;
|
||||||
tv.tv_usec = 0;
|
|
||||||
if (!pn53x_SAMConfiguration (pnd, 0x01, &tv)) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case POWERDOWN: {
|
case POWERDOWN: {
|
||||||
if (-1 == pn532_uart_wakeup(pnd)) {
|
if ((res = pn532_uart_wakeup(pnd)) < 0) {
|
||||||
return false;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -260,43 +317,43 @@ pn532_uart_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
byte_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
uint8_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||||
size_t szFrame = 0;
|
size_t szFrame = 0;
|
||||||
|
|
||||||
if (!pn53x_build_frame (abtFrame, &szFrame, pbtData, szData)) {
|
if ((res = pn53x_build_frame (abtFrame, &szFrame, pbtData, szData)) < 0) {
|
||||||
pnd->iLastError = EINVALARG;
|
pnd->last_error = res;
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = uart_send (DRIVER_DATA(pnd)->port, abtFrame, szFrame, timeout);
|
res = uart_send (DRIVER_DATA(pnd)->port, abtFrame, szFrame, timeout);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
|
||||||
pnd->iLastError = res;
|
pnd->last_error = res;
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_t abtRxBuf[6];
|
uint8_t abtRxBuf[6];
|
||||||
res = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 6, 0, timeout);
|
res = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 6, 0, timeout);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to read ACK");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to read ACK");
|
||||||
pnd->iLastError = res;
|
pnd->last_error = res;
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pn53x_check_ack_frame (pnd, abtRxBuf, sizeof(abtRxBuf))) {
|
if (pn53x_check_ack_frame (pnd, abtRxBuf, sizeof(abtRxBuf)) == 0) {
|
||||||
// The PN53x is running the sent command
|
// The PN53x is running the sent command
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
return true;
|
return NFC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen, struct timeval *timeout)
|
pn532_uart_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, int timeout)
|
||||||
{
|
{
|
||||||
byte_t abtRxBuf[5];
|
uint8_t abtRxBuf[5];
|
||||||
size_t len;
|
size_t len;
|
||||||
void * abort_p = NULL;
|
void *abort_p = NULL;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
abort_p = &(DRIVER_DATA (pnd)->iAbortFds[1]);
|
abort_p = &(DRIVER_DATA (pnd)->iAbortFds[1]);
|
||||||
|
@ -304,51 +361,50 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
|
||||||
abort_p = (void*)&(DRIVER_DATA (pnd)->abort_flag);
|
abort_p = (void*)&(DRIVER_DATA (pnd)->abort_flag);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pnd->iLastError = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 5, abort_p, timeout);
|
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 5, abort_p, timeout);
|
||||||
|
|
||||||
if (abort_p && (EOPABORT == pnd->iLastError)) {
|
if (abort_p && (NFC_EOPABORTED == pnd->last_error)) {
|
||||||
pn532_uart_ack (pnd);
|
return pn532_uart_ack (pnd);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pnd->iLastError != 0) {
|
if (pnd->last_error != 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
const byte_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
|
const uint8_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
|
||||||
if (0 != (memcmp (abtRxBuf, pn53x_preamble, 3))) {
|
if (0 != (memcmp (abtRxBuf, pn53x_preamble, 3))) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
|
if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
|
||||||
// Error frame
|
// Error frame
|
||||||
uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout);
|
uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 3, 0, timeout);
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Application level error detected");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Application level error detected");
|
||||||
pnd->iLastError = EFRAISERRFRAME;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
} else if ((0xff == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
|
} else if ((0xff == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
|
||||||
// Extended frame
|
// Extended frame
|
||||||
pnd->iLastError = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout);
|
pnd->last_error = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout);
|
||||||
if (pnd->iLastError) return -1;
|
if (pnd->last_error) return pnd->last_error;
|
||||||
|
|
||||||
// (abtRxBuf[0] << 8) + abtRxBuf[1] (LEN) include TFI + (CC+1)
|
// (abtRxBuf[0] << 8) + abtRxBuf[1] (LEN) include TFI + (CC+1)
|
||||||
len = (abtRxBuf[0] << 8) + abtRxBuf[1] - 2;
|
len = (abtRxBuf[0] << 8) + abtRxBuf[1] - 2;
|
||||||
if (((abtRxBuf[0] + abtRxBuf[1] + abtRxBuf[2]) % 256) != 0) {
|
if (((abtRxBuf[0] + abtRxBuf[1] + abtRxBuf[2]) % 256) != 0) {
|
||||||
// TODO: Retry
|
// TODO: Retry
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Normal frame
|
// Normal frame
|
||||||
if (256 != (abtRxBuf[3] + abtRxBuf[4])) {
|
if (256 != (abtRxBuf[3] + abtRxBuf[4])) {
|
||||||
// TODO: Retry
|
// TODO: Retry
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// abtRxBuf[3] (LEN) include TFI + (CC+1)
|
// abtRxBuf[3] (LEN) include TFI + (CC+1)
|
||||||
|
@ -357,77 +413,78 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
|
||||||
|
|
||||||
if (len > szDataLen) {
|
if (len > szDataLen) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len);
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TFI + PD0 (CC+1)
|
// TFI + PD0 (CC+1)
|
||||||
pnd->iLastError = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout);
|
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
|
||||||
if (pnd->iLastError != 0) {
|
if (pnd->last_error != 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abtRxBuf[0] != 0xD5) {
|
if (abtRxBuf[0] != 0xD5) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "TFI Mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "TFI Mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abtRxBuf[1] != CHIP_DATA (pnd)->ui8LastCommand + 1) {
|
if (abtRxBuf[1] != CHIP_DATA (pnd)->last_command + 1) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Command Code verification failed");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Command Code verification failed");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
pnd->iLastError = uart_receive (DRIVER_DATA(pnd)->port, pbtData, len, 0, timeout);
|
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, pbtData, len, 0, timeout);
|
||||||
if (pnd->iLastError != 0) {
|
if (pnd->last_error != 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pnd->iLastError = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout);
|
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
|
||||||
if (pnd->iLastError != 0) {
|
if (pnd->last_error != 0) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_t btDCS = (256 - 0xD5);
|
uint8_t btDCS = (256 - 0xD5);
|
||||||
btDCS -= CHIP_DATA (pnd)->ui8LastCommand + 1;
|
btDCS -= CHIP_DATA (pnd)->last_command + 1;
|
||||||
for (size_t szPos = 0; szPos < len; szPos++) {
|
for (size_t szPos = 0; szPos < len; szPos++) {
|
||||||
btDCS -= pbtData[szPos];
|
btDCS -= pbtData[szPos];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (btDCS != abtRxBuf[0]) {
|
if (btDCS != abtRxBuf[0]) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Data checksum mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Data checksum mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0x00 != abtRxBuf[1]) {
|
if (0x00 != abtRxBuf[1]) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
// The PN53x command is done and we successfully received the reply
|
// The PN53x command is done and we successfully received the reply
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pn532_uart_ack (nfc_device_t * pnd)
|
pn532_uart_ack (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
|
int res = 0;
|
||||||
if (POWERDOWN == CHIP_DATA(pnd)->power_mode) {
|
if (POWERDOWN == CHIP_DATA(pnd)->power_mode) {
|
||||||
if (-1 == pn532_uart_wakeup(pnd)) {
|
if ((res = pn532_uart_wakeup(pnd)) < 0) {
|
||||||
return -1;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (0 == uart_send (DRIVER_DATA(pnd)->port, pn53x_ack_frame, sizeof (pn53x_ack_frame), NULL)) ? 0 : -1;
|
return (uart_send (DRIVER_DATA(pnd)->port, pn53x_ack_frame, sizeof (pn53x_ack_frame), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int
|
||||||
pn532_uart_abort_command (nfc_device_t * pnd)
|
pn532_uart_abort_command (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
if (pnd) {
|
if (pnd) {
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
@ -437,7 +494,7 @@ pn532_uart_abort_command (nfc_device_t * pnd)
|
||||||
DRIVER_DATA (pnd)->abort_flag = true;
|
DRIVER_DATA (pnd)->abort_flag = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return true;
|
return NFC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct pn53x_io pn532_uart_io = {
|
const struct pn53x_io pn532_uart_io = {
|
||||||
|
@ -445,12 +502,12 @@ const struct pn53x_io pn532_uart_io = {
|
||||||
.receive = pn532_uart_receive,
|
.receive = pn532_uart_receive,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct nfc_driver_t pn532_uart_driver = {
|
const struct nfc_driver pn532_uart_driver = {
|
||||||
.name = PN532_UART_DRIVER_NAME,
|
.name = PN532_UART_DRIVER_NAME,
|
||||||
.probe = pn532_uart_probe,
|
.probe = pn532_uart_probe,
|
||||||
.connect = pn532_uart_connect,
|
.open = pn532_uart_open,
|
||||||
.disconnect = pn532_uart_disconnect,
|
.close = pn532_uart_close,
|
||||||
.strerror = pn53x_strerror,
|
.strerror = pn53x_strerror,
|
||||||
|
|
||||||
.initiator_init = pn53x_initiator_init,
|
.initiator_init = pn53x_initiator_init,
|
||||||
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
||||||
|
@ -468,7 +525,8 @@ const struct nfc_driver_t pn532_uart_driver = {
|
||||||
.target_send_bits = pn53x_target_send_bits,
|
.target_send_bits = pn53x_target_send_bits,
|
||||||
.target_receive_bits = pn53x_target_receive_bits,
|
.target_receive_bits = pn53x_target_receive_bits,
|
||||||
|
|
||||||
.configure = pn53x_configure,
|
.device_set_property_bool = pn53x_set_property_bool,
|
||||||
|
.device_set_property_int = pn53x_set_property_int,
|
||||||
|
|
||||||
.abort_command = pn532_uart_abort_command,
|
.abort_command = pn532_uart_abort_command,
|
||||||
.idle = pn53x_idle,
|
.idle = pn53x_idle,
|
||||||
|
|
|
@ -29,13 +29,13 @@
|
||||||
|
|
||||||
# include <nfc/nfc-types.h>
|
# include <nfc/nfc-types.h>
|
||||||
|
|
||||||
bool pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
|
bool pn532_uart_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t *pszDeviceFound);
|
||||||
|
|
||||||
nfc_device_t *pn532_uart_connect (const nfc_device_desc_t * pndd);
|
nfc_device *pn532_uart_open (const nfc_connstring connstring);
|
||||||
void pn532_uart_disconnect (nfc_device_t * pnd);
|
void pn532_uart_close (nfc_device *pnd);
|
||||||
bool pn532_uart_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout);
|
int pn532_uart_send (nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout);
|
||||||
int pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struct timeval *timeout);
|
int pn532_uart_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szData, int timeout);
|
||||||
|
|
||||||
extern const struct nfc_driver_t pn532_uart_driver;
|
extern const struct nfc_driver pn532_uart_driver;
|
||||||
|
|
||||||
#endif // ! __NFC_DRIVER_PN532_UART_H__
|
#endif // ! __NFC_DRIVER_PN532_UART_H__
|
||||||
|
|
|
@ -32,10 +32,11 @@
|
||||||
Thanks to d18c7db and Okko for example code
|
Thanks to d18c7db and Okko for example code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
// Under POSIX system, we use libusb (>= 0.1.12)
|
// Under POSIX system, we use libusb (>= 0.1.12)
|
||||||
|
@ -58,44 +59,13 @@ Thanks to d18c7db and Okko for example code
|
||||||
#include "chips/pn53x-internal.h"
|
#include "chips/pn53x-internal.h"
|
||||||
#include "drivers/pn53x_usb.h"
|
#include "drivers/pn53x_usb.h"
|
||||||
|
|
||||||
#define PN53X_USB_DRIVER_NAME "PN53x USB"
|
#define PN53X_USB_DRIVER_NAME "pn53x_usb"
|
||||||
#define LOG_CATEGORY "libnfc.driver.pn53x_usb"
|
#define LOG_CATEGORY "libnfc.driver.pn53x_usb"
|
||||||
|
|
||||||
#define USB_INFINITE_TIMEOUT 0
|
#define USB_INFINITE_TIMEOUT 0
|
||||||
|
|
||||||
#define DRIVER_DATA(pnd) ((struct pn53x_usb_data*)(pnd->driver_data))
|
#define DRIVER_DATA(pnd) ((struct pn53x_usb_data*)(pnd->driver_data))
|
||||||
|
|
||||||
/* This modified from some GNU example _not_ to overwrite y */
|
|
||||||
int timeval_subtract(struct timeval *result,
|
|
||||||
const struct timeval *x,
|
|
||||||
const struct timeval *y)
|
|
||||||
{
|
|
||||||
struct timeval tmp;
|
|
||||||
|
|
||||||
tmp.tv_sec = y->tv_sec;
|
|
||||||
tmp.tv_usec = y->tv_usec;
|
|
||||||
|
|
||||||
/* Perform the carry for the later subtraction */
|
|
||||||
if (x->tv_usec < y->tv_usec) {
|
|
||||||
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
|
|
||||||
tmp.tv_usec -= 1000000 * nsec;
|
|
||||||
tmp.tv_sec += nsec;
|
|
||||||
}
|
|
||||||
if (x->tv_usec - y->tv_usec > 1000000) {
|
|
||||||
int nsec = (x->tv_usec - y->tv_usec) / 1000000;
|
|
||||||
tmp.tv_usec += 1000000 * nsec;
|
|
||||||
tmp.tv_sec -= nsec;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute the time remaining to wait.
|
|
||||||
tv_usec is certainly positive. */
|
|
||||||
result->tv_sec = x->tv_sec - tmp.tv_sec;
|
|
||||||
result->tv_usec = x->tv_usec - tmp.tv_usec;
|
|
||||||
|
|
||||||
/* Return 1 if result is negative. */
|
|
||||||
return x->tv_sec < tmp.tv_sec;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
NXP_PN531,
|
NXP_PN531,
|
||||||
|
@ -117,21 +87,12 @@ struct pn53x_usb_data {
|
||||||
|
|
||||||
const struct pn53x_io pn53x_usb_io;
|
const struct pn53x_io pn53x_usb_io;
|
||||||
bool pn53x_usb_get_usb_device_name (struct usb_device *dev, usb_dev_handle *udev, char *buffer, size_t len);
|
bool pn53x_usb_get_usb_device_name (struct usb_device *dev, usb_dev_handle *udev, char *buffer, size_t len);
|
||||||
bool pn53x_usb_init (nfc_device_t *pnd);
|
int pn53x_usb_init (nfc_device *pnd);
|
||||||
|
|
||||||
int
|
int
|
||||||
pn53x_usb_bulk_read (struct pn53x_usb_data *data, byte_t abtRx[], const size_t szRx, struct timeval *timeout)
|
pn53x_usb_bulk_read (struct pn53x_usb_data *data, uint8_t abtRx[], const size_t szRx, const int timeout)
|
||||||
{
|
{
|
||||||
int timeout_ms = USB_INFINITE_TIMEOUT;
|
int res = usb_bulk_read (data->pudh, data->uiEndPointIn, (char *) abtRx, szRx, timeout);
|
||||||
if (timeout) {
|
|
||||||
timeout_ms = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
|
|
||||||
if (timeout_ms == USB_INFINITE_TIMEOUT) {
|
|
||||||
// timeout < 1 ms
|
|
||||||
timeout_ms++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int res = usb_bulk_read (data->pudh, data->uiEndPointIn, (char *) abtRx, szRx, timeout_ms);
|
|
||||||
if (res > 0) {
|
if (res > 0) {
|
||||||
LOG_HEX ("RX", abtRx, res);
|
LOG_HEX ("RX", abtRx, res);
|
||||||
} else if (res < 0) {
|
} else if (res < 0) {
|
||||||
|
@ -142,18 +103,14 @@ pn53x_usb_bulk_read (struct pn53x_usb_data *data, byte_t abtRx[], const size_t s
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pn53x_usb_bulk_write (struct pn53x_usb_data *data, byte_t abtTx[], const size_t szTx, struct timeval *timeout)
|
pn53x_usb_bulk_write (struct pn53x_usb_data *data, uint8_t abtTx[], const size_t szTx, const int timeout)
|
||||||
{
|
{
|
||||||
LOG_HEX ("TX", abtTx, szTx);
|
LOG_HEX ("TX", abtTx, szTx);
|
||||||
int timeout_ms = USB_INFINITE_TIMEOUT;
|
int res = usb_bulk_write (data->pudh, data->uiEndPointOut, (char *) abtTx, szTx, timeout);
|
||||||
if (timeout)
|
|
||||||
timeout_ms = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
|
|
||||||
|
|
||||||
int res = usb_bulk_write (data->pudh, data->uiEndPointOut, (char *) abtTx, szTx, timeout_ms);
|
|
||||||
if (res > 0) {
|
if (res > 0) {
|
||||||
// HACK This little hack is a well know problem of USB, see http://www.libusb.org/ticket/6 for more details
|
// HACK This little hack is a well know problem of USB, see http://www.libusb.org/ticket/6 for more details
|
||||||
if ((res % data->uiMaxPacketSize) == 0) {
|
if ((res % data->uiMaxPacketSize) == 0) {
|
||||||
usb_bulk_write (data->pudh, data->uiEndPointOut, "\0", 0, timeout_ms);
|
usb_bulk_write (data->pudh, data->uiEndPointOut, "\0", 0, timeout);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to write to USB (%s)", _usb_strerror (res));
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to write to USB (%s)", _usb_strerror (res));
|
||||||
|
@ -189,7 +146,7 @@ pn53x_usb_get_device_model (uint16_t vendor_id, uint16_t product_id)
|
||||||
return UNKNOWN;
|
return UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pn53x_usb_ack (nfc_device_t * pnd);
|
int pn53x_usb_ack (nfc_device *pnd);
|
||||||
|
|
||||||
// Find transfer endpoints for bulk transfers
|
// Find transfer endpoints for bulk transfers
|
||||||
void
|
void
|
||||||
|
@ -222,7 +179,7 @@ pn53x_usb_get_end_points (struct usb_device *dev, struct pn53x_usb_data *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pn53x_usb_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
|
pn53x_usb_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t *pszDeviceFound)
|
||||||
{
|
{
|
||||||
usb_init ();
|
usb_init ();
|
||||||
|
|
||||||
|
@ -275,13 +232,13 @@ pn53x_usb_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * psz
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pn53x_usb_get_usb_device_name (dev, udev, pnddDevices[*pszDeviceFound].acDevice, sizeof (pnddDevices[*pszDeviceFound].acDevice));
|
// pn53x_usb_get_usb_device_name (dev, udev, pnddDevices[*pszDeviceFound].acDevice, sizeof (pnddDevices[*pszDeviceFound].acDevice));
|
||||||
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "device found: Bus %s Device %s", bus->dirname, dev->filename);
|
||||||
usb_close (udev);
|
usb_close (udev);
|
||||||
pnddDevices[*pszDeviceFound].pcDriver = PN53X_USB_DRIVER_NAME;
|
snprintf (connstrings[*pszDeviceFound], sizeof(nfc_connstring), "%s:%s:%s", PN53X_USB_DRIVER_NAME, bus->dirname, dev->filename);
|
||||||
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
|
|
||||||
(*pszDeviceFound)++;
|
(*pszDeviceFound)++;
|
||||||
// Test if we reach the maximum "wanted" devices
|
// Test if we reach the maximum "wanted" devices
|
||||||
if ((*pszDeviceFound) == szDevices) {
|
if ((*pszDeviceFound) == connstrings_len) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,6 +249,38 @@ pn53x_usb_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * psz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct pn53x_usb_descriptor {
|
||||||
|
char *dirname;
|
||||||
|
char *filename;
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
pn53x_usb_connstring_decode (const nfc_connstring connstring, struct pn53x_usb_descriptor *desc)
|
||||||
|
{
|
||||||
|
int n = strlen (connstring) + 1;
|
||||||
|
char *driver_name = malloc (n);
|
||||||
|
char *dirname = malloc (n);
|
||||||
|
char *filename = malloc (n);
|
||||||
|
|
||||||
|
driver_name[0] = '\0';
|
||||||
|
|
||||||
|
int res = sscanf (connstring, "%[^:]:%[^:]:%[^:]", driver_name, dirname, filename);
|
||||||
|
|
||||||
|
if (!res || (0 != strcmp (driver_name, PN53X_USB_DRIVER_NAME))) {
|
||||||
|
// Driver name does not match.
|
||||||
|
res = 0;
|
||||||
|
} else {
|
||||||
|
desc->dirname = strdup (dirname);
|
||||||
|
desc->filename = strdup (filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
free (driver_name);
|
||||||
|
free (dirname);
|
||||||
|
free (filename);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pn53x_usb_get_usb_device_name (struct usb_device *dev, usb_dev_handle *udev, char *buffer, size_t len)
|
pn53x_usb_get_usb_device_name (struct usb_device *dev, usb_dev_handle *udev, char *buffer, size_t len)
|
||||||
{
|
{
|
||||||
|
@ -319,10 +308,17 @@ pn53x_usb_get_usb_device_name (struct usb_device *dev, usb_dev_handle *udev, cha
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_device_t *
|
nfc_device *
|
||||||
pn53x_usb_connect (const nfc_device_desc_t *pndd)
|
pn53x_usb_open (const nfc_connstring connstring)
|
||||||
{
|
{
|
||||||
nfc_device_t *pnd = NULL;
|
nfc_device *pnd = NULL;
|
||||||
|
struct pn53x_usb_descriptor desc = { NULL, NULL } ;
|
||||||
|
int connstring_decode_level = pn53x_usb_connstring_decode (connstring, &desc);
|
||||||
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%d element(s) have been decoded from \"%s\"", connstring_decode_level, connstring);
|
||||||
|
if (connstring_decode_level < 1) {
|
||||||
|
goto free_mem;
|
||||||
|
}
|
||||||
|
|
||||||
struct pn53x_usb_data data = {
|
struct pn53x_usb_data data = {
|
||||||
.pudh = NULL,
|
.pudh = NULL,
|
||||||
.uiEndPointIn = 0,
|
.uiEndPointIn = 0,
|
||||||
|
@ -330,95 +326,118 @@ pn53x_usb_connect (const nfc_device_desc_t *pndd)
|
||||||
};
|
};
|
||||||
struct usb_bus *bus;
|
struct usb_bus *bus;
|
||||||
struct usb_device *dev;
|
struct usb_device *dev;
|
||||||
uint32_t uiBusIndex;
|
|
||||||
|
|
||||||
usb_init ();
|
usb_init ();
|
||||||
|
|
||||||
uiBusIndex = pndd->uiBusIndex;
|
int res;
|
||||||
|
// usb_find_busses will find all of the busses on the system. Returns the
|
||||||
|
// number of changes since previous call to this function (total of new
|
||||||
|
// busses and busses removed).
|
||||||
|
if ((res = usb_find_busses () < 0)) {
|
||||||
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to find USB busses (%s)", _usb_strerror (res));
|
||||||
|
goto free_mem;
|
||||||
|
}
|
||||||
|
// usb_find_devices will find all of the devices on each bus. This should be
|
||||||
|
// called after usb_find_busses. Returns the number of changes since the
|
||||||
|
// previous call to this function (total of new device and devices removed).
|
||||||
|
if ((res = usb_find_devices () < 0)) {
|
||||||
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to find USB devices (%s)", _usb_strerror (res));
|
||||||
|
goto free_mem;
|
||||||
|
}
|
||||||
|
|
||||||
for (bus = usb_get_busses (); bus; bus = bus->next) {
|
for (bus = usb_get_busses (); bus; bus = bus->next) {
|
||||||
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex--) {
|
if (connstring_decode_level > 1) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Checking device %04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
|
// A specific bus have been specified
|
||||||
if (uiBusIndex == 0) {
|
if (0 != strcmp (bus->dirname, desc.dirname))
|
||||||
// Open the USB device
|
continue;
|
||||||
data.pudh = usb_open (dev);
|
}
|
||||||
// Retrieve end points
|
for (dev = bus->devices; dev; dev = dev->next) {
|
||||||
pn53x_usb_get_end_points (dev, &data);
|
if (connstring_decode_level > 2) {
|
||||||
// Set configuration
|
// A specific dev have been specified
|
||||||
int res = usb_set_configuration (data.pudh, 1);
|
if (0 != strcmp (dev->filename, desc.filename))
|
||||||
if (res < 0) {
|
continue;
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to set USB configuration (%s)", _usb_strerror (res));
|
|
||||||
if (EPERM == -res) {
|
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_WARN, "Please double check USB permissions for device %04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
|
|
||||||
}
|
|
||||||
usb_close (data.pudh);
|
|
||||||
// we failed to use the specified device
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = usb_claim_interface (data.pudh, 0);
|
|
||||||
if (res < 0) {
|
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to claim USB interface (%s)", _usb_strerror (res));
|
|
||||||
usb_close (data.pudh);
|
|
||||||
// we failed to use the specified device
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
data.model = pn53x_usb_get_device_model (dev->descriptor.idVendor, dev->descriptor.idProduct);
|
|
||||||
// Allocate memory for the device info and specification, fill it and return the info
|
|
||||||
pnd = nfc_device_new ();
|
|
||||||
pn53x_usb_get_usb_device_name (dev, data.pudh, pnd->acName, sizeof (pnd->acName));
|
|
||||||
|
|
||||||
pnd->driver_data = malloc(sizeof(struct pn53x_usb_data));
|
|
||||||
*DRIVER_DATA (pnd) = data;
|
|
||||||
|
|
||||||
// Alloc and init chip's data
|
|
||||||
pn53x_data_new (pnd, &pn53x_usb_io);
|
|
||||||
|
|
||||||
switch (DRIVER_DATA (pnd)->model) {
|
|
||||||
// empirical tuning
|
|
||||||
case ASK_LOGO:
|
|
||||||
CHIP_DATA (pnd)->timer_correction = 50;
|
|
||||||
break;
|
|
||||||
case SCM_SCL3711:
|
|
||||||
case NXP_PN533:
|
|
||||||
CHIP_DATA (pnd)->timer_correction = 46;
|
|
||||||
break;
|
|
||||||
case NXP_PN531:
|
|
||||||
CHIP_DATA (pnd)->timer_correction = 50;
|
|
||||||
break;
|
|
||||||
case SONY_PN531:
|
|
||||||
CHIP_DATA (pnd)->timer_correction = 54;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pnd->driver = &pn53x_usb_driver;
|
|
||||||
|
|
||||||
// HACK1: Send first an ACK as Abort command, to reset chip before talking to it:
|
|
||||||
pn53x_usb_ack (pnd);
|
|
||||||
|
|
||||||
// HACK2: Then send a GetFirmware command to resync USB toggle bit between host & device
|
|
||||||
// in case host used set_configuration and expects the device to have reset its toggle bit, which PN53x doesn't do
|
|
||||||
if (!pn53x_usb_init (pnd)) {
|
|
||||||
usb_close (data.pudh);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
DRIVER_DATA (pnd)->abort_flag = false;
|
|
||||||
return pnd;
|
|
||||||
}
|
}
|
||||||
|
// Open the USB device
|
||||||
|
data.pudh = usb_open (dev);
|
||||||
|
// Retrieve end points
|
||||||
|
pn53x_usb_get_end_points (dev, &data);
|
||||||
|
// Set configuration
|
||||||
|
int res = usb_set_configuration (data.pudh, 1);
|
||||||
|
if (res < 0) {
|
||||||
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to set USB configuration (%s)", _usb_strerror (res));
|
||||||
|
if (EPERM == -res) {
|
||||||
|
log_put (LOG_CATEGORY, NFC_PRIORITY_WARN, "Please double check USB permissions for device %04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
|
||||||
|
}
|
||||||
|
usb_close (data.pudh);
|
||||||
|
// we failed to use the specified device
|
||||||
|
goto free_mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = usb_claim_interface (data.pudh, 0);
|
||||||
|
if (res < 0) {
|
||||||
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to claim USB interface (%s)", _usb_strerror (res));
|
||||||
|
usb_close (data.pudh);
|
||||||
|
// we failed to use the specified device
|
||||||
|
goto free_mem;
|
||||||
|
}
|
||||||
|
data.model = pn53x_usb_get_device_model (dev->descriptor.idVendor, dev->descriptor.idProduct);
|
||||||
|
// Allocate memory for the device info and specification, fill it and return the info
|
||||||
|
pnd = nfc_device_new (connstring);
|
||||||
|
pn53x_usb_get_usb_device_name (dev, data.pudh, pnd->name, sizeof (pnd->name));
|
||||||
|
|
||||||
|
pnd->driver_data = malloc(sizeof(struct pn53x_usb_data));
|
||||||
|
*DRIVER_DATA (pnd) = data;
|
||||||
|
|
||||||
|
// Alloc and init chip's data
|
||||||
|
pn53x_data_new (pnd, &pn53x_usb_io);
|
||||||
|
|
||||||
|
switch (DRIVER_DATA (pnd)->model) {
|
||||||
|
// empirical tuning
|
||||||
|
case ASK_LOGO:
|
||||||
|
CHIP_DATA (pnd)->timer_correction = 50;
|
||||||
|
break;
|
||||||
|
case SCM_SCL3711:
|
||||||
|
case NXP_PN533:
|
||||||
|
CHIP_DATA (pnd)->timer_correction = 46;
|
||||||
|
break;
|
||||||
|
case NXP_PN531:
|
||||||
|
CHIP_DATA (pnd)->timer_correction = 50;
|
||||||
|
break;
|
||||||
|
case SONY_PN531:
|
||||||
|
CHIP_DATA (pnd)->timer_correction = 54;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pnd->driver = &pn53x_usb_driver;
|
||||||
|
|
||||||
|
// HACK1: Send first an ACK as Abort command, to reset chip before talking to it:
|
||||||
|
pn53x_usb_ack (pnd);
|
||||||
|
|
||||||
|
// HACK2: Then send a GetFirmware command to resync USB toggle bit between host & device
|
||||||
|
// in case host used set_configuration and expects the device to have reset its toggle bit, which PN53x doesn't do
|
||||||
|
if (pn53x_usb_init (pnd) < 0) {
|
||||||
|
usb_close (data.pudh);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
DRIVER_DATA (pnd)->abort_flag = false;
|
||||||
|
goto free_mem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We ran out of devices before the index required
|
// We ran out of devices before the index required
|
||||||
return NULL;
|
goto free_mem;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
// Free allocated structure on error.
|
// Free allocated structure on error.
|
||||||
nfc_device_free (pnd);
|
nfc_device_free (pnd);
|
||||||
return NULL;
|
free_mem:
|
||||||
|
free (desc.dirname);
|
||||||
|
free (desc.filename);
|
||||||
|
return pnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pn53x_usb_disconnect (nfc_device_t * pnd)
|
pn53x_usb_close (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
pn53x_usb_ack (pnd);
|
pn53x_usb_ack (pnd);
|
||||||
|
|
||||||
|
@ -444,31 +463,29 @@ pn53x_usb_disconnect (nfc_device_t * pnd)
|
||||||
|
|
||||||
#define PN53X_USB_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
|
#define PN53X_USB_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
|
||||||
|
|
||||||
bool
|
int
|
||||||
pn53x_usb_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout)
|
pn53x_usb_send (nfc_device *pnd, const uint8_t *pbtData, const size_t szData, const int timeout)
|
||||||
{
|
{
|
||||||
byte_t abtFrame[PN53X_USB_BUFFER_LEN] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
uint8_t abtFrame[PN53X_USB_BUFFER_LEN] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||||
size_t szFrame = 0;
|
size_t szFrame = 0;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
pn53x_build_frame (abtFrame, &szFrame, pbtData, szData);
|
pn53x_build_frame (abtFrame, &szFrame, pbtData, szData);
|
||||||
|
|
||||||
int res = pn53x_usb_bulk_write (DRIVER_DATA (pnd), abtFrame, szFrame, timeout);
|
if ((res = pn53x_usb_bulk_write (DRIVER_DATA (pnd), abtFrame, szFrame, timeout)) < 0) {
|
||||||
|
pnd->last_error = res;
|
||||||
if (res < 0) {
|
return pnd->last_error;
|
||||||
pnd->iLastError = ECOMIO;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_t abtRxBuf[PN53X_USB_BUFFER_LEN];
|
uint8_t abtRxBuf[PN53X_USB_BUFFER_LEN];
|
||||||
res = pn53x_usb_bulk_read (DRIVER_DATA (pnd), abtRxBuf, sizeof (abtRxBuf), timeout);
|
if ((res = pn53x_usb_bulk_read (DRIVER_DATA (pnd), abtRxBuf, sizeof (abtRxBuf), timeout)) < 0) {
|
||||||
if (res < 0) {
|
pnd->last_error = res;
|
||||||
pnd->iLastError = ECOMIO;
|
|
||||||
// try to interrupt current device state
|
// try to interrupt current device state
|
||||||
pn53x_usb_ack(pnd);
|
pn53x_usb_ack(pnd);
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pn53x_check_ack_frame (pnd, abtRxBuf, res)) {
|
if (pn53x_check_ack_frame (pnd, abtRxBuf, res) == 0) {
|
||||||
// The PN53x is running the sent command
|
// The PN53x is running the sent command
|
||||||
} else {
|
} else {
|
||||||
// For some reasons (eg. send another command while a previous one is
|
// For some reasons (eg. send another command while a previous one is
|
||||||
|
@ -478,94 +495,80 @@ pn53x_usb_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData,
|
||||||
// pn53x_usb_receive()) will be able to retreive the correct response
|
// pn53x_usb_receive()) will be able to retreive the correct response
|
||||||
// packet.
|
// packet.
|
||||||
// FIXME Sony reader is also affected by this bug but NACK is not supported
|
// FIXME Sony reader is also affected by this bug but NACK is not supported
|
||||||
int res = pn53x_usb_bulk_write (DRIVER_DATA (pnd), (byte_t *)pn53x_nack_frame, sizeof(pn53x_nack_frame), timeout);
|
if ((res = pn53x_usb_bulk_write (DRIVER_DATA (pnd), (uint8_t *)pn53x_nack_frame, sizeof(pn53x_nack_frame), timeout)) < 0) {
|
||||||
if (res < 0) {
|
pnd->last_error = res;
|
||||||
pnd->iLastError = ECOMIO;
|
|
||||||
// try to interrupt current device state
|
// try to interrupt current device state
|
||||||
pn53x_usb_ack(pnd);
|
pn53x_usb_ack(pnd);
|
||||||
return false;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return NFC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define USB_TIMEOUT_PER_PASS 200
|
||||||
int
|
int
|
||||||
pn53x_usb_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen, struct timeval *timeout)
|
pn53x_usb_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, const int timeout)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
off_t offset = 0;
|
off_t offset = 0;
|
||||||
|
|
||||||
byte_t abtRxBuf[PN53X_USB_BUFFER_LEN];
|
uint8_t abtRxBuf[PN53X_USB_BUFFER_LEN];
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If no timeout is specified but the command is blocking, force a 250ms
|
* If no timeout is specified but the command is blocking, force a 200ms (USB_TIMEOUT_PER_PASS)
|
||||||
* timeout to allow breaking the loop if the user wants to stop it.
|
* timeout to allow breaking the loop if the user wants to stop it.
|
||||||
*/
|
*/
|
||||||
const struct timeval fixed_timeout = {
|
int usb_timeout;
|
||||||
.tv_sec = 0,
|
int remaining_time = timeout;
|
||||||
.tv_usec = 250000,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct timeval remaining_time, usb_timeout;
|
|
||||||
if (timeout) {
|
|
||||||
remaining_time = *timeout;
|
|
||||||
}
|
|
||||||
read:
|
read:
|
||||||
if (timeout) {
|
if (timeout == USB_INFINITE_TIMEOUT) {
|
||||||
// A user-provided timeout is set, we have to cut it in multiple chunk to be able to keep an nfc_abort_command() mecanism
|
usb_timeout = USB_TIMEOUT_PER_PASS;
|
||||||
struct timeval tmp;
|
|
||||||
if (1 == timeval_subtract (&tmp, &remaining_time, &fixed_timeout)) {
|
|
||||||
// The subtraction result is negative
|
|
||||||
usb_timeout = remaining_time;
|
|
||||||
remaining_time.tv_sec = 0;
|
|
||||||
remaining_time.tv_usec = 0;
|
|
||||||
} else {
|
|
||||||
usb_timeout = fixed_timeout;
|
|
||||||
remaining_time = tmp;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// No user-provided timeout, we will wait infinitely but we need 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() mecanism
|
||||||
usb_timeout = fixed_timeout;
|
remaining_time -= USB_TIMEOUT_PER_PASS;
|
||||||
|
if (remaining_time <= 0) {
|
||||||
|
pnd->last_error = NFC_ETIMEOUT;
|
||||||
|
return pnd->last_error;
|
||||||
|
} else {
|
||||||
|
usb_timeout = MIN(remaining_time, USB_TIMEOUT_PER_PASS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((usb_timeout.tv_sec == 0) && (usb_timeout.tv_usec == 0)) {
|
|
||||||
pnd->iLastError = ECOMTIMEOUT;
|
res = pn53x_usb_bulk_read (DRIVER_DATA (pnd), abtRxBuf, sizeof (abtRxBuf), usb_timeout);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
res = pn53x_usb_bulk_read (DRIVER_DATA (pnd), abtRxBuf, sizeof (abtRxBuf), &usb_timeout);
|
|
||||||
|
|
||||||
if (res == -USB_TIMEDOUT) {
|
if (res == -USB_TIMEDOUT) {
|
||||||
if (DRIVER_DATA (pnd)->abort_flag) {
|
if (DRIVER_DATA (pnd)->abort_flag) {
|
||||||
DRIVER_DATA (pnd)->abort_flag = false;
|
DRIVER_DATA (pnd)->abort_flag = false;
|
||||||
pn53x_usb_ack (pnd);
|
pn53x_usb_ack (pnd);
|
||||||
pnd->iLastError = EOPABORT;
|
pnd->last_error = NFC_EOPABORTED;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
} else {
|
} else {
|
||||||
goto read;
|
goto read;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = res;
|
||||||
// try to interrupt current device state
|
// try to interrupt current device state
|
||||||
pn53x_usb_ack(pnd);
|
pn53x_usb_ack(pnd);
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
const byte_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
|
const uint8_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
|
||||||
if (0 != (memcmp (abtRxBuf, pn53x_preamble, 3))) {
|
if (0 != (memcmp (abtRxBuf, pn53x_preamble, 3))) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
offset += 3;
|
offset += 3;
|
||||||
|
|
||||||
if ((0x01 == abtRxBuf[offset]) && (0xff == abtRxBuf[offset + 1])) {
|
if ((0x01 == abtRxBuf[offset]) && (0xff == abtRxBuf[offset + 1])) {
|
||||||
// Error frame
|
// Error frame
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Application level error detected");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Application level error detected");
|
||||||
pnd->iLastError = EFRAISERRFRAME;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
} else if ((0xff == abtRxBuf[offset]) && (0xff == abtRxBuf[offset + 1])) {
|
} else if ((0xff == abtRxBuf[offset]) && (0xff == abtRxBuf[offset + 1])) {
|
||||||
// Extended frame
|
// Extended frame
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
@ -575,8 +578,8 @@ read:
|
||||||
if (((abtRxBuf[offset] + abtRxBuf[offset + 1] + abtRxBuf[offset + 2]) % 256) != 0) {
|
if (((abtRxBuf[offset] + abtRxBuf[offset + 1] + abtRxBuf[offset + 2]) % 256) != 0) {
|
||||||
// TODO: Retry
|
// TODO: Retry
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
offset += 3;
|
offset += 3;
|
||||||
} else {
|
} else {
|
||||||
|
@ -584,8 +587,8 @@ read:
|
||||||
if (256 != (abtRxBuf[offset] + abtRxBuf[offset + 1])) {
|
if (256 != (abtRxBuf[offset] + abtRxBuf[offset + 1])) {
|
||||||
// TODO: Retry
|
// TODO: Retry
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// abtRxBuf[3] (LEN) include TFI + (CC+1)
|
// abtRxBuf[3] (LEN) include TFI + (CC+1)
|
||||||
|
@ -595,75 +598,76 @@ read:
|
||||||
|
|
||||||
if (len > szDataLen) {
|
if (len > szDataLen) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len);
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len);
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TFI + PD0 (CC+1)
|
// TFI + PD0 (CC+1)
|
||||||
if (abtRxBuf[offset] != 0xD5) {
|
if (abtRxBuf[offset] != 0xD5) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "TFI Mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "TFI Mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
offset += 1;
|
offset += 1;
|
||||||
|
|
||||||
if (abtRxBuf[offset] != CHIP_DATA (pnd)->ui8LastCommand + 1) {
|
if (abtRxBuf[offset] != CHIP_DATA (pnd)->last_command + 1) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Command Code verification failed");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Command Code verification failed");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
offset += 1;
|
offset += 1;
|
||||||
|
|
||||||
memcpy (pbtData, abtRxBuf + offset, len);
|
memcpy (pbtData, abtRxBuf + offset, len);
|
||||||
offset += len;
|
offset += len;
|
||||||
|
|
||||||
byte_t btDCS = (256 - 0xD5);
|
uint8_t btDCS = (256 - 0xD5);
|
||||||
btDCS -= CHIP_DATA (pnd)->ui8LastCommand + 1;
|
btDCS -= CHIP_DATA (pnd)->last_command + 1;
|
||||||
for (size_t szPos = 0; szPos < len; szPos++) {
|
for (size_t szPos = 0; szPos < len; szPos++) {
|
||||||
btDCS -= pbtData[szPos];
|
btDCS -= pbtData[szPos];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (btDCS != abtRxBuf[offset]) {
|
if (btDCS != abtRxBuf[offset]) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Data checksum mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Data checksum mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
offset += 1;
|
offset += 1;
|
||||||
|
|
||||||
if (0x00 != abtRxBuf[offset]) {
|
if (0x00 != abtRxBuf[offset]) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
|
||||||
pnd->iLastError = ECOMIO;
|
pnd->last_error = NFC_EIO;
|
||||||
return -1;
|
return pnd->last_error;
|
||||||
}
|
}
|
||||||
// The PN53x command is done and we successfully received the reply
|
// The PN53x command is done and we successfully received the reply
|
||||||
pnd->iLastError = 0;
|
pnd->last_error = 0;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pn53x_usb_ack (nfc_device_t * pnd)
|
pn53x_usb_ack (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
return pn53x_usb_bulk_write (DRIVER_DATA (pnd), (byte_t *) pn53x_ack_frame, sizeof (pn53x_ack_frame), NULL);
|
return pn53x_usb_bulk_write (DRIVER_DATA (pnd), (uint8_t *) pn53x_ack_frame, sizeof (pn53x_ack_frame), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int
|
||||||
pn53x_usb_init (nfc_device_t *pnd)
|
pn53x_usb_init (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
|
int res = 0;
|
||||||
// Sometimes PN53x USB doesn't reply ACK one the first frame, so we need to send a dummy one...
|
// Sometimes PN53x USB doesn't reply ACK one the first frame, so we need to send a dummy one...
|
||||||
//pn53x_check_communication (pnd); // Sony RC-S360 doesn't support this command for now so let's use a get_firmware_version instead:
|
//pn53x_check_communication (pnd); // Sony RC-S360 doesn't support this command for now so let's use a get_firmware_version instead:
|
||||||
const byte_t abtCmd[] = { GetFirmwareVersion };
|
const uint8_t abtCmd[] = { GetFirmwareVersion };
|
||||||
pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL, NULL);
|
pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, 0, 0);
|
||||||
// ...and we don't care about error
|
// ...and we don't care about error
|
||||||
pnd->iLastError = 0;
|
pnd->last_error = 0;
|
||||||
if (SONY_RCS360 == DRIVER_DATA (pnd)->model) {
|
if (SONY_RCS360 == DRIVER_DATA (pnd)->model) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "SONY RC-S360 initialization.");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "SONY RC-S360 initialization.");
|
||||||
const byte_t abtCmd2[] = { 0x18, 0x01 };
|
const uint8_t abtCmd2[] = { 0x18, 0x01 };
|
||||||
pn53x_transceive (pnd, abtCmd2, sizeof (abtCmd2), NULL, NULL, NULL);
|
pn53x_transceive (pnd, abtCmd2, sizeof (abtCmd2), NULL, 0, 0);
|
||||||
pn53x_usb_ack (pnd);
|
pn53x_usb_ack (pnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pn53x_init (pnd))
|
if ((res = pn53x_init (pnd)) < 0)
|
||||||
return false;
|
return res;
|
||||||
|
|
||||||
if (ASK_LOGO == DRIVER_DATA (pnd)->model) {
|
if (ASK_LOGO == DRIVER_DATA (pnd)->model) {
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "ASK LoGO initialization.");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "ASK LoGO initialization.");
|
||||||
|
@ -700,42 +704,43 @@ On ASK LoGO hardware:
|
||||||
pn53x_write_register (pnd, PN53X_SFR_P3, 0xFF, _BV (P30) | _BV (P31) | _BV (P33) | _BV (P35));
|
pn53x_write_register (pnd, PN53X_SFR_P3, 0xFF, _BV (P30) | _BV (P31) | _BV (P33) | _BV (P35));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return NFC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int
|
||||||
pn53x_usb_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable)
|
pn53x_usb_set_property_bool (nfc_device *pnd, const nfc_property property, const bool bEnable)
|
||||||
{
|
{
|
||||||
if (!pn53x_configure (pnd, ndo, bEnable))
|
int res = 0;
|
||||||
return false;
|
if ((res = pn53x_set_property_bool (pnd, property, bEnable)) < 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
switch (DRIVER_DATA (pnd)->model) {
|
switch (DRIVER_DATA (pnd)->model) {
|
||||||
case ASK_LOGO:
|
case ASK_LOGO:
|
||||||
if (NDO_ACTIVATE_FIELD == ndo) {
|
if (NP_ACTIVATE_FIELD == property) {
|
||||||
/* Switch on/off LED2 and Progressive Field GPIO according to ACTIVATE_FIELD option */
|
/* Switch on/off LED2 and Progressive Field GPIO according to ACTIVATE_FIELD option */
|
||||||
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Switch progressive field %s", bEnable ? "On" : "Off");
|
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Switch progressive field %s", bEnable ? "On" : "Off");
|
||||||
if (!pn53x_write_register (pnd, PN53X_SFR_P3, _BV(P31) | _BV(P34), bEnable ? _BV (P34) : _BV (P31)))
|
if ((res = pn53x_write_register (pnd, PN53X_SFR_P3, _BV(P31) | _BV(P34), bEnable ? _BV (P34) : _BV (P31))) < 0)
|
||||||
return false;
|
return NFC_ECHIP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCM_SCL3711:
|
case SCM_SCL3711:
|
||||||
if (NDO_ACTIVATE_FIELD == ndo) {
|
if (NP_ACTIVATE_FIELD == property) {
|
||||||
// Switch on/off LED according to ACTIVATE_FIELD option
|
// Switch on/off LED according to ACTIVATE_FIELD option
|
||||||
if (!pn53x_write_register (pnd, PN53X_SFR_P3, _BV (P32), bEnable ? 0 : _BV (P32)))
|
if ((res = pn53x_write_register (pnd, PN53X_SFR_P3, _BV (P32), bEnable ? 0 : _BV (P32))) < 0)
|
||||||
return false;
|
return res;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return NFC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int
|
||||||
pn53x_usb_abort_command (nfc_device_t * pnd)
|
pn53x_usb_abort_command (nfc_device *pnd)
|
||||||
{
|
{
|
||||||
DRIVER_DATA (pnd)->abort_flag = true;
|
DRIVER_DATA (pnd)->abort_flag = true;
|
||||||
return true;
|
return NFC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct pn53x_io pn53x_usb_io = {
|
const struct pn53x_io pn53x_usb_io = {
|
||||||
|
@ -743,12 +748,12 @@ const struct pn53x_io pn53x_usb_io = {
|
||||||
.receive = pn53x_usb_receive,
|
.receive = pn53x_usb_receive,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct nfc_driver_t pn53x_usb_driver = {
|
const struct nfc_driver pn53x_usb_driver = {
|
||||||
.name = PN53X_USB_DRIVER_NAME,
|
.name = PN53X_USB_DRIVER_NAME,
|
||||||
.probe = pn53x_usb_probe,
|
.probe = pn53x_usb_probe,
|
||||||
.connect = pn53x_usb_connect,
|
.open = pn53x_usb_open,
|
||||||
.disconnect = pn53x_usb_disconnect,
|
.close = pn53x_usb_close,
|
||||||
.strerror = pn53x_strerror,
|
.strerror = pn53x_strerror,
|
||||||
|
|
||||||
.initiator_init = pn53x_initiator_init,
|
.initiator_init = pn53x_initiator_init,
|
||||||
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
.initiator_select_passive_target = pn53x_initiator_select_passive_target,
|
||||||
|
@ -766,7 +771,8 @@ const struct nfc_driver_t pn53x_usb_driver = {
|
||||||
.target_send_bits = pn53x_target_send_bits,
|
.target_send_bits = pn53x_target_send_bits,
|
||||||
.target_receive_bits = pn53x_target_receive_bits,
|
.target_receive_bits = pn53x_target_receive_bits,
|
||||||
|
|
||||||
.configure = pn53x_usb_configure,
|
.device_set_property_bool = pn53x_usb_set_property_bool,
|
||||||
|
.device_set_property_int = pn53x_set_property_int,
|
||||||
|
|
||||||
.abort_command = pn53x_usb_abort_command,
|
.abort_command = pn53x_usb_abort_command,
|
||||||
.idle = pn53x_idle,
|
.idle = pn53x_idle,
|
||||||
|
|
|
@ -23,18 +23,20 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __NFC_DRIVER_PN53X_USB_H__
|
#ifndef __NFC_DRIVER_PN53X_USB_H__
|
||||||
# define __NFC_DRIVER_PN53X_USB_H__
|
#define __NFC_DRIVER_PN53X_USB_H__
|
||||||
|
|
||||||
# include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
# include <nfc/nfc-types.h>
|
#include <nfc/nfc-types.h>
|
||||||
|
|
||||||
bool pn53x_usb_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
|
#include "nfc-internal.h"
|
||||||
nfc_device_t *pn53x_usb_connect (const nfc_device_desc_t * pndd);
|
|
||||||
bool pn53x_usb_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout);
|
|
||||||
int pn53x_usb_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struct timeval *timeout);
|
|
||||||
void pn53x_usb_disconnect (nfc_device_t * pnd);
|
|
||||||
|
|
||||||
extern const struct nfc_driver_t pn53x_usb_driver;
|
bool pn53x_usb_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t *pszDeviceFound);
|
||||||
|
nfc_device *pn53x_usb_open (const nfc_connstring connstring);
|
||||||
|
int pn53x_usb_send (nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout);
|
||||||
|
int pn53x_usb_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szData, int timeout);
|
||||||
|
void pn53x_usb_close (nfc_device *pnd);
|
||||||
|
|
||||||
|
extern const struct nfc_driver pn53x_usb_driver;
|
||||||
|
|
||||||
#endif // ! __NFC_DRIVER_PN53X_USB_H__
|
#endif // ! __NFC_DRIVER_PN53X_USB_H__
|
||||||
|
|
|
@ -32,30 +32,30 @@
|
||||||
#include <nfc/nfc.h>
|
#include <nfc/nfc.h>
|
||||||
|
|
||||||
void
|
void
|
||||||
iso14443a_crc (byte_t * pbtData, size_t szLen, byte_t * pbtCrc)
|
iso14443a_crc (uint8_t *pbtData, size_t szLen, uint8_t *pbtCrc)
|
||||||
{
|
{
|
||||||
byte_t bt;
|
uint8_t bt;
|
||||||
uint32_t wCrc = 0x6363;
|
uint32_t wCrc = 0x6363;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
bt = *pbtData++;
|
bt = *pbtData++;
|
||||||
bt = (bt ^ (byte_t) (wCrc & 0x00FF));
|
bt = (bt ^ (uint8_t) (wCrc & 0x00FF));
|
||||||
bt = (bt ^ (bt << 4));
|
bt = (bt ^ (bt << 4));
|
||||||
wCrc = (wCrc >> 8) ^ ((uint32_t) bt << 8) ^ ((uint32_t) bt << 3) ^ ((uint32_t) bt >> 4);
|
wCrc = (wCrc >> 8) ^ ((uint32_t) bt << 8) ^ ((uint32_t) bt << 3) ^ ((uint32_t) bt >> 4);
|
||||||
} while (--szLen);
|
} while (--szLen);
|
||||||
|
|
||||||
*pbtCrc++ = (byte_t) (wCrc & 0xFF);
|
*pbtCrc++ = (uint8_t) (wCrc & 0xFF);
|
||||||
*pbtCrc = (byte_t) ((wCrc >> 8) & 0xFF);
|
*pbtCrc = (uint8_t) ((wCrc >> 8) & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
iso14443a_crc_append (byte_t * pbtData, size_t szLen)
|
iso14443a_crc_append (uint8_t *pbtData, size_t szLen)
|
||||||
{
|
{
|
||||||
iso14443a_crc (pbtData, szLen, pbtData + szLen);
|
iso14443a_crc (pbtData, szLen, pbtData + szLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_t *
|
uint8_t *
|
||||||
iso14443a_locate_historical_bytes (byte_t * pbtAts, size_t szAts, size_t * pszTk)
|
iso14443a_locate_historical_bytes (uint8_t *pbtAts, size_t szAts, size_t *pszTk)
|
||||||
{
|
{
|
||||||
if (szAts) {
|
if (szAts) {
|
||||||
size_t offset = 1;
|
size_t offset = 1;
|
||||||
|
@ -82,7 +82,7 @@ iso14443a_locate_historical_bytes (byte_t * pbtAts, size_t szAts, size_t * pszTk
|
||||||
* @see ISO/IEC 14443-3 (6.4.4 UID contents and cascade levels)
|
* @see ISO/IEC 14443-3 (6.4.4 UID contents and cascade levels)
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
iso14443_cascade_uid (const byte_t abtUID[], const size_t szUID, byte_t * pbtCascadedUID, size_t * pszCascadedUID)
|
iso14443_cascade_uid (const uint8_t abtUID[], const size_t szUID, uint8_t *pbtCascadedUID, size_t *pszCascadedUID)
|
||||||
{
|
{
|
||||||
switch (szUID) {
|
switch (szUID) {
|
||||||
case 7:
|
case 7:
|
||||||
|
|
|
@ -17,9 +17,10 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <log4c.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ log_init (void)
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
if (__log_init_counter == 0) {
|
if (__log_init_counter == 0) {
|
||||||
res = log4c_init ();
|
res = 0;
|
||||||
}
|
}
|
||||||
if (!res) {
|
if (!res) {
|
||||||
__log_init_counter++;
|
__log_init_counter++;
|
||||||
|
@ -45,7 +46,7 @@ log_fini (void)
|
||||||
int res = 0;
|
int res = 0;
|
||||||
if (__log_init_counter >= 1) {
|
if (__log_init_counter >= 1) {
|
||||||
if (__log_init_counter == 1) {
|
if (__log_init_counter == 1) {
|
||||||
res = log4c_fini ();
|
res = 0;
|
||||||
}
|
}
|
||||||
__log_init_counter--;
|
__log_init_counter--;
|
||||||
} else {
|
} else {
|
||||||
|
@ -55,12 +56,12 @@ log_fini (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
log_put (char *category, int priority, char *format, ...)
|
log_put (char *category, char *priority, char *format, ...)
|
||||||
{
|
{
|
||||||
const log4c_category_t *cat = log4c_category_get (category);
|
va_list va;
|
||||||
if (log4c_category_is_priority_enabled (cat, priority)) {
|
va_start (va, format);
|
||||||
va_list va;
|
printf ("%s\t%s\t", priority, category);
|
||||||
va_start (va, format);
|
vprintf (format, va);
|
||||||
log4c_category_vlog (cat, priority, format, va);
|
printf ("\n");
|
||||||
}
|
va_end (va);
|
||||||
}
|
}
|
99
libnfc/log.h
99
libnfc/log.h
|
@ -18,69 +18,44 @@
|
||||||
#ifndef __LOG_H__
|
#ifndef __LOG_H__
|
||||||
#define __LOG_H__
|
#define __LOG_H__
|
||||||
|
|
||||||
#if defined(HAS_LOG4C) && HAS_LOG4C /* log4c have been detected */
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif // HAVE_CONFIG_H
|
||||||
|
|
||||||
#define LOGGING 1
|
#if defined DEBUG
|
||||||
|
// User want debug features
|
||||||
#include <log4c.h>
|
#define LOGGING 1
|
||||||
|
int log_init (void);
|
||||||
int log_init (void);
|
int log_fini (void);
|
||||||
int log_fini (void);
|
void log_put (char *category, char *priority, char *format, ...);
|
||||||
void log_put (char *category, int priority, char *format, ...);
|
|
||||||
|
#define NFC_PRIORITY_FATAL "fatal"
|
||||||
#define NFC_PRIORITY_FATAL LOG4C_PRIORITY_FATAL
|
#define NFC_PRIORITY_ALERT "alert"
|
||||||
#define NFC_PRIORITY_ALERT LOG4C_PRIORITY_ALERT
|
#define NFC_PRIORITY_CRIT "critical"
|
||||||
#define NFC_PRIORITY_CRIT LOG4C_PRIORITY_CRIT
|
#define NFC_PRIORITY_ERROR "error"
|
||||||
#define NFC_PRIORITY_ERROR LOG4C_PRIORITY_ERROR
|
#define NFC_PRIORITY_WARN "warning"
|
||||||
#define NFC_PRIORITY_WARN LOG4C_PRIORITY_WARN
|
#define NFC_PRIORITY_NOTICE "notice"
|
||||||
#define NFC_PRIORITY_NOTICE LOG4C_PRIORITY_NOTICE
|
#define NFC_PRIORITY_INFO "info"
|
||||||
#define NFC_PRIORITY_INFO LOG4C_PRIORITY_INFO
|
#define NFC_PRIORITY_DEBUG "debug"
|
||||||
#define NFC_PRIORITY_DEBUG LOG4C_PRIORITY_DEBUG
|
#define NFC_PRIORITY_TRACE "trace"
|
||||||
#define NFC_PRIORITY_TRACE LOG4C_PRIORITY_TRACE
|
#else
|
||||||
|
// No logging
|
||||||
#elif defined(DEBUG) /* no available log4c but debug is enabled */
|
#define log_init() (0)
|
||||||
|
#define log_fini() (0)
|
||||||
#define LOGGING 1
|
#define log_msg(category, priority, message) do {} while (0)
|
||||||
|
#define log_set_appender(category, appender) do {} while (0)
|
||||||
#define log_init() (0)
|
#define log_put(category, priority, format, ...) do {} while (0)
|
||||||
#define log_fini() (0)
|
|
||||||
#define log_msg(category, priority, message) do {} while (0)
|
#define NFC_PRIORITY_FATAL 8
|
||||||
#define log_set_appender(category, appender) do {} while (0)
|
#define NFC_PRIORITY_ALERT 7
|
||||||
#define log_put(category, priority, format, ...) do { \
|
#define NFC_PRIORITY_CRIT 6
|
||||||
fprintf(stderr, "%s - ", category); \
|
#define NFC_PRIORITY_ERROR 5
|
||||||
fprintf(stderr, format, ##__VA_ARGS__); \
|
#define NFC_PRIORITY_WARN 4
|
||||||
fprintf(stderr, "\n"); \
|
#define NFC_PRIORITY_NOTICE 3
|
||||||
} while (0)
|
#define NFC_PRIORITY_INFO 2
|
||||||
|
#define NFC_PRIORITY_DEBUG 1
|
||||||
#define NFC_PRIORITY_FATAL 8
|
#define NFC_PRIORITY_TRACE 0
|
||||||
#define NFC_PRIORITY_ALERT 7
|
#endif /* HAS_LOG4C, DEBUG */
|
||||||
#define NFC_PRIORITY_CRIT 6
|
|
||||||
#define NFC_PRIORITY_ERROR 5
|
|
||||||
#define NFC_PRIORITY_WARN 4
|
|
||||||
#define NFC_PRIORITY_NOTICE 3
|
|
||||||
#define NFC_PRIORITY_INFO 2
|
|
||||||
#define NFC_PRIORITY_DEBUG 1
|
|
||||||
#define NFC_PRIORITY_TRACE 0
|
|
||||||
|
|
||||||
#else /* no available log4c and debug is disabled */
|
|
||||||
|
|
||||||
#define log_init() (0)
|
|
||||||
#define log_fini() (0)
|
|
||||||
#define log_msg(category, priority, message) do {} while (0)
|
|
||||||
#define log_set_appender(category, appender) do {} while (0)
|
|
||||||
#define log_put(category, priority, format, ...) do {} while (0)
|
|
||||||
|
|
||||||
#define NFC_PRIORITY_FATAL 8
|
|
||||||
#define NFC_PRIORITY_ALERT 7
|
|
||||||
#define NFC_PRIORITY_CRIT 6
|
|
||||||
#define NFC_PRIORITY_ERROR 5
|
|
||||||
#define NFC_PRIORITY_WARN 4
|
|
||||||
#define NFC_PRIORITY_NOTICE 3
|
|
||||||
#define NFC_PRIORITY_INFO 2
|
|
||||||
#define NFC_PRIORITY_DEBUG 1
|
|
||||||
#define NFC_PRIORITY_TRACE 0
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @macro LOG_HEX
|
* @macro LOG_HEX
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
#include "mirror-subr.h"
|
#include "mirror-subr.h"
|
||||||
|
|
||||||
static const byte_t ByteMirror[256] = {
|
static const uint8_t ByteMirror[256] = {
|
||||||
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30,
|
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30,
|
||||||
0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98,
|
0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98,
|
||||||
0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64,
|
0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64,
|
||||||
|
@ -53,14 +53,14 @@ static const byte_t ByteMirror[256] = {
|
||||||
0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
|
0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
byte_t
|
uint8_t
|
||||||
mirror (byte_t bt)
|
mirror (uint8_t bt)
|
||||||
{
|
{
|
||||||
return ByteMirror[bt];
|
return ByteMirror[bt];
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mirror_bytes (byte_t * pbts, size_t szLen)
|
mirror_bytes (uint8_t *pbts, size_t szLen)
|
||||||
{
|
{
|
||||||
size_t szByteNr;
|
size_t szByteNr;
|
||||||
|
|
||||||
|
@ -73,13 +73,13 @@ mirror_bytes (byte_t * pbts, size_t szLen)
|
||||||
uint32_t
|
uint32_t
|
||||||
mirror32 (uint32_t ui32Bits)
|
mirror32 (uint32_t ui32Bits)
|
||||||
{
|
{
|
||||||
mirror_bytes ((byte_t *) & ui32Bits, 4);
|
mirror_bytes ((uint8_t *) & ui32Bits, 4);
|
||||||
return ui32Bits;
|
return ui32Bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
mirror64 (uint64_t ui64Bits)
|
mirror64 (uint64_t ui64Bits)
|
||||||
{
|
{
|
||||||
mirror_bytes ((byte_t *) & ui64Bits, 8);
|
mirror_bytes ((uint8_t *) & ui64Bits, 8);
|
||||||
return ui64Bits;
|
return ui64Bits;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,9 @@
|
||||||
# include <nfc/nfc-types.h>
|
# include <nfc/nfc-types.h>
|
||||||
|
|
||||||
|
|
||||||
byte_t mirror (byte_t bt);
|
uint8_t mirror (uint8_t bt);
|
||||||
uint32_t mirror32 (uint32_t ui32Bits);
|
uint32_t mirror32 (uint32_t ui32Bits);
|
||||||
uint64_t mirror64 (uint64_t ui64Bits);
|
uint64_t mirror64 (uint64_t ui64Bits);
|
||||||
void mirror_byte_ts (byte_t * pbts, size_t szLen);
|
void mirror_uint8_ts (uint8_t *pbts, size_t szLen);
|
||||||
|
|
||||||
#endif // _LIBNFC_MIRROR_SUBR_H_
|
#endif // _LIBNFC_MIRROR_SUBR_H_
|
||||||
|
|
|
@ -19,12 +19,13 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file nfc-device.c
|
* @file nfc-device.c
|
||||||
* @brief Provide internal function to manipulate nfc_device_t type
|
* @brief Provide internal function to manipulate nfc_device type
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* vim:set et sw=2 ts=2: */
|
/* vim:set et sw=2 ts=2: */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
@ -32,10 +33,10 @@
|
||||||
|
|
||||||
#include "nfc-internal.h"
|
#include "nfc-internal.h"
|
||||||
|
|
||||||
nfc_device_t *
|
nfc_device *
|
||||||
nfc_device_new (void)
|
nfc_device_new (const nfc_connstring connstring)
|
||||||
{
|
{
|
||||||
nfc_device_t *res = malloc (sizeof (*res));
|
nfc_device *res = malloc (sizeof (*res));
|
||||||
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
err (EXIT_FAILURE, "nfc_device_new: malloc");
|
err (EXIT_FAILURE, "nfc_device_new: malloc");
|
||||||
|
@ -49,7 +50,8 @@ nfc_device_new (void)
|
||||||
res->bPar = false;
|
res->bPar = false;
|
||||||
res->bEasyFraming = false;
|
res->bEasyFraming = false;
|
||||||
res->bAutoIso14443_4 = false;
|
res->bAutoIso14443_4 = false;
|
||||||
res->iLastError = 0;
|
res->last_error = 0;
|
||||||
|
memcpy (res->connstring, connstring, sizeof (res->connstring));
|
||||||
res->driver_data = NULL;
|
res->driver_data = NULL;
|
||||||
res->chip_data = NULL;
|
res->chip_data = NULL;
|
||||||
|
|
||||||
|
@ -57,7 +59,7 @@ nfc_device_new (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nfc_device_free (nfc_device_t *nfc_device)
|
nfc_device_free (nfc_device *nfc_device)
|
||||||
{
|
{
|
||||||
if (nfc_device) {
|
if (nfc_device) {
|
||||||
free (nfc_device->driver_data);
|
free (nfc_device->driver_data);
|
||||||
|
|
|
@ -28,26 +28,26 @@
|
||||||
#include "iso7816.h"
|
#include "iso7816.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
nfc_emulate_target (nfc_device_t* pnd, struct nfc_emulator *emulator)
|
nfc_emulate_target (nfc_device *pnd, struct nfc_emulator *emulator)
|
||||||
{
|
{
|
||||||
byte_t abtRx[ISO7816_SHORT_R_APDU_MAX_LEN];
|
uint8_t abtRx[ISO7816_SHORT_R_APDU_MAX_LEN];
|
||||||
size_t szRx = sizeof(abtRx);
|
int szRx;
|
||||||
byte_t abtTx[ISO7816_SHORT_C_APDU_MAX_LEN];
|
uint8_t abtTx[ISO7816_SHORT_C_APDU_MAX_LEN];
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
if (!nfc_target_init (pnd, emulator->target, abtRx, &szRx)) {
|
if ((szRx = nfc_target_init (pnd, emulator->target, abtRx, sizeof(abtRx), 0)) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (res >= 0) {
|
while (res >= 0) {
|
||||||
res = emulator->state_machine->io (emulator, abtRx, szRx, abtTx, sizeof (abtTx));
|
res = emulator->state_machine->io (emulator, abtRx, (size_t) szRx, abtTx, sizeof (abtTx));
|
||||||
if (res > 0) {
|
if (res > 0) {
|
||||||
if (!nfc_target_send_bytes(pnd, abtTx, res, NULL)) {
|
if (nfc_target_send_bytes(pnd, abtTx, res, 0) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
if (!nfc_target_receive_bytes(pnd, abtRx, &szRx, NULL)) {
|
if ((res = nfc_target_receive_bytes(pnd, abtRx, (size_t) szRx, 0)) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,39 +23,38 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nfc/nfc.h>
|
#include <nfc/nfc.h>
|
||||||
#include <nfc/nfc-emulation.h>
|
|
||||||
|
|
||||||
void
|
void
|
||||||
prepare_initiator_data (const nfc_modulation_t nm, byte_t **ppbtInitiatorData, size_t * pszInitiatorData)
|
prepare_initiator_data (const nfc_modulation nm, uint8_t **ppbtInitiatorData, size_t * pszInitiatorData)
|
||||||
{
|
{
|
||||||
switch (nm.nmt) {
|
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)
|
// Application Family Identifier (AFI) must equals 0x00 in order to wakeup all ISO14443-B PICCs (see ISO/IEC 14443-3)
|
||||||
*ppbtInitiatorData = (byte_t *) "\x00";
|
*ppbtInitiatorData = (uint8_t *) "\x00";
|
||||||
*pszInitiatorData = 1;
|
*pszInitiatorData = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NMT_ISO14443BI: {
|
case NMT_ISO14443BI: {
|
||||||
// APGEN
|
// APGEN
|
||||||
*ppbtInitiatorData = (byte_t *) "\x01\x0b\x3f\x80";
|
*ppbtInitiatorData = (uint8_t *) "\x01\x0b\x3f\x80";
|
||||||
*pszInitiatorData = 4;
|
*pszInitiatorData = 4;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NMT_ISO14443B2SR: {
|
case NMT_ISO14443B2SR: {
|
||||||
// Get_UID
|
// Get_UID
|
||||||
*ppbtInitiatorData = (byte_t *) "\x0b";
|
*ppbtInitiatorData = (uint8_t *) "\x0b";
|
||||||
*pszInitiatorData = 1;
|
*pszInitiatorData = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NMT_ISO14443B2CT: {
|
case NMT_ISO14443B2CT: {
|
||||||
// SELECT-ALL
|
// SELECT-ALL
|
||||||
*ppbtInitiatorData = (byte_t *) "\x9F\xFF\xFF";
|
*ppbtInitiatorData = (uint8_t *) "\x9F\xFF\xFF";
|
||||||
*pszInitiatorData = 3;
|
*pszInitiatorData = 3;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NMT_FELICA: {
|
case NMT_FELICA: {
|
||||||
// polling payload must be present (see ISO/IEC 18092 11.2.2.5)
|
// polling payload must be present (see ISO/IEC 18092 11.2.2.5)
|
||||||
*ppbtInitiatorData = (byte_t *) "\x00\xff\xff\x01\x00";
|
*ppbtInitiatorData = (uint8_t *) "\x00\xff\xff\x01\x00";
|
||||||
*pszInitiatorData = 5;
|
*pszInitiatorData = 5;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -23,24 +23,25 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __NFC_INTERNAL_H__
|
#ifndef __NFC_INTERNAL_H__
|
||||||
# define __NFC_INTERNAL_H__
|
#define __NFC_INTERNAL_H__
|
||||||
|
|
||||||
# include <nfc/nfc-types.h>
|
#include <stdbool.h>
|
||||||
# include <stdbool.h>
|
#include <err.h>
|
||||||
# include <err.h>
|
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
|
|
||||||
|
#include "nfc/nfc.h"
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @macro HAL
|
* @macro HAL
|
||||||
* @brief Execute corresponding driver function if exists.
|
* @brief Execute corresponding driver function if exists.
|
||||||
*/
|
*/
|
||||||
#define HAL( FUNCTION, ... ) pnd->iLastError = 0; \
|
#define HAL( FUNCTION, ... ) pnd->last_error = 0; \
|
||||||
if (pnd->driver->FUNCTION) { \
|
if (pnd->driver->FUNCTION) { \
|
||||||
return pnd->driver->FUNCTION( __VA_ARGS__ ); \
|
return pnd->driver->FUNCTION( __VA_ARGS__ ); \
|
||||||
} else { \
|
} else { \
|
||||||
pnd->iLastError = EDEVNOTSUP; \
|
pnd->last_error = NFC_EDEVNOTSUPP; \
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,40 +126,72 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct nfc_driver_t {
|
struct nfc_driver {
|
||||||
const char *name;
|
const char *name;
|
||||||
bool (*probe)(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
|
bool (*probe)(nfc_connstring connstrings[], size_t connstrings_len, size_t * pszDeviceFound);
|
||||||
nfc_device_t * (*connect)(const nfc_device_desc_t * pndd);
|
struct nfc_device *(*open) (const nfc_connstring connstring);
|
||||||
void (*disconnect)(nfc_device_t * pnd);
|
void (*close) (struct nfc_device *pnd);
|
||||||
const char *(*strerror)(const nfc_device_t * pnd);
|
const char *(*strerror) (const struct nfc_device *pnd);
|
||||||
|
|
||||||
bool (*initiator_init) (nfc_device_t * pnd);
|
int (*initiator_init) (struct nfc_device *pnd);
|
||||||
bool (*initiator_select_passive_target) (nfc_device_t * pnd, const nfc_modulation_t nm, const byte_t * pbtInitData, const size_t szInitData, nfc_target_t * pnt);
|
int (*initiator_select_passive_target) (struct nfc_device *pnd, const nfc_modulation nm, const uint8_t * pbtInitData, const size_t szInitData, nfc_target * pnt);
|
||||||
bool (*initiator_poll_target) (nfc_device_t * pnd, const nfc_modulation_t * pnmModulations, const size_t szModulations, const uint8_t uiPollNr, const uint8_t btPeriod, nfc_target_t * pnt);
|
int (*initiator_poll_target) (struct nfc_device *pnd, const nfc_modulation * pnmModulations, const size_t szModulations, const uint8_t uiPollNr, const uint8_t btPeriod, nfc_target * pnt);
|
||||||
bool (*initiator_select_dep_target) (nfc_device_t * pnd, const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr, const nfc_dep_info_t * pndiInitiator, nfc_target_t * pnt);
|
int (*initiator_select_dep_target) (struct nfc_device *pnd, const nfc_dep_mode ndm, const nfc_baud_rate nbr, const nfc_dep_info * pndiInitiator, nfc_target * pnt, const int timeout);
|
||||||
bool (*initiator_deselect_target) (nfc_device_t * pnd);
|
int (*initiator_deselect_target) (struct nfc_device *pnd);
|
||||||
bool (*initiator_transceive_bytes) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
|
int (*initiator_transceive_bytes) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTx, uint8_t * pbtRx, size_t * pszRx, int timeout);
|
||||||
bool (*initiator_transceive_bits) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
|
int (*initiator_transceive_bits) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTxBits, const uint8_t * pbtTxPar, uint8_t * pbtRx, uint8_t * pbtRxPar);
|
||||||
bool (*initiator_transceive_bytes_timed) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx, uint32_t * cycles);
|
int (*initiator_transceive_bytes_timed) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTx, uint8_t * pbtRx, uint32_t * cycles);
|
||||||
bool (*initiator_transceive_bits_timed) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar, uint32_t * cycles);
|
int (*initiator_transceive_bits_timed) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTxBits, const uint8_t * pbtTxPar, uint8_t * pbtRx, uint8_t * pbtRxPar, uint32_t * cycles);
|
||||||
|
|
||||||
bool (*target_init) (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx);
|
int (*target_init) (struct nfc_device *pnd, nfc_target * pnt, uint8_t * pbtRx, const size_t szRx, int timeout);
|
||||||
bool (*target_send_bytes) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, struct timeval *timeout);
|
int (*target_send_bytes) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTx, int timeout);
|
||||||
bool (*target_receive_bytes) (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
|
int (*target_receive_bytes) (struct nfc_device *pnd, uint8_t * pbtRx, const size_t szRxLen, int timeout);
|
||||||
bool (*target_send_bits) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar);
|
int (*target_send_bits) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTxBits, const uint8_t * pbtTxPar);
|
||||||
bool (*target_receive_bits) (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
|
int (*target_receive_bits) (struct nfc_device *pnd, uint8_t * pbtRx, const size_t szRxLen, uint8_t * pbtRxPar);
|
||||||
|
|
||||||
bool (*configure) (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
|
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);
|
||||||
|
|
||||||
bool (*abort_command) (nfc_device_t * pnd);
|
int (*abort_command) (struct nfc_device *pnd);
|
||||||
bool (*idle) (nfc_device_t * pnd);
|
int (*idle) (struct nfc_device *pnd);
|
||||||
};
|
};
|
||||||
|
|
||||||
nfc_device_t *nfc_device_new (void);
|
# define DEVICE_NAME_LENGTH 256
|
||||||
void nfc_device_free (nfc_device_t *nfc_device);
|
# define DEVICE_PORT_LENGTH 64
|
||||||
|
|
||||||
void iso14443_cascade_uid (const byte_t abtUID[], const size_t szUID, byte_t * pbtCascadedUID, size_t * pszCascadedUID);
|
/**
|
||||||
|
* @struct nfc_device
|
||||||
|
* @brief NFC device information
|
||||||
|
*/
|
||||||
|
struct nfc_device {
|
||||||
|
const struct nfc_driver *driver;
|
||||||
|
void *driver_data;
|
||||||
|
void *chip_data;
|
||||||
|
|
||||||
void prepare_initiator_data (const nfc_modulation_t nm, byte_t **ppbtInitiatorData, size_t * pszInitiatorData);
|
/** Device name string, including device wrapper firmware */
|
||||||
|
char name[DEVICE_NAME_LENGTH];
|
||||||
|
/** Device connection string */
|
||||||
|
nfc_connstring connstring;
|
||||||
|
/** Is the CRC automaticly added, checked and removed from the frames */
|
||||||
|
bool bCrc;
|
||||||
|
/** Does the chip handle parity bits, all parities are handled as data */
|
||||||
|
bool bPar;
|
||||||
|
/** Should the chip handle frames encapsulation and chaining */
|
||||||
|
bool bEasyFraming;
|
||||||
|
/** Should the chip switch automatically activate ISO14443-4 when
|
||||||
|
selecting tags supporting it? */
|
||||||
|
bool bAutoIso14443_4;
|
||||||
|
/** Supported modulation encoded in a byte */
|
||||||
|
uint8_t btSupportByte;
|
||||||
|
/** Last reported error */
|
||||||
|
int last_error;
|
||||||
|
};
|
||||||
|
|
||||||
|
nfc_device *nfc_device_new (const nfc_connstring connstring);
|
||||||
|
void nfc_device_free (nfc_device *dev);
|
||||||
|
|
||||||
|
void iso14443_cascade_uid (const uint8_t abtUID[], const size_t szUID, uint8_t * pbtCascadedUID, size_t * pszCascadedUID);
|
||||||
|
|
||||||
|
void prepare_initiator_data (const nfc_modulation nm, uint8_t **ppbtInitiatorData, size_t * pszInitiatorData);
|
||||||
|
|
||||||
#endif // __NFC_INTERNAL_H__
|
#endif // __NFC_INTERNAL_H__
|
||||||
|
|
667
libnfc/nfc.c
667
libnfc/nfc.c
File diff suppressed because it is too large
Load diff
2
log4crc
2
log4crc
|
@ -21,5 +21,5 @@
|
||||||
<layout name="basic" type="basic"/>
|
<layout name="basic" type="basic"/>
|
||||||
<layout name="dated" type="dated"/>
|
<layout name="dated" type="dated"/>
|
||||||
|
|
||||||
<category name="libnfc" priority="trace" appender="stdout"/>
|
<category name="libnfc" priority="trace" appender="stderr"/>
|
||||||
</log4c>
|
</log4c>
|
||||||
|
|
|
@ -9,7 +9,9 @@ TESTS_ENVIRONMENT = NO_MAKE=yes CUTTER="$(CUTTER)"
|
||||||
|
|
||||||
cutter_unit_test_libs = \
|
cutter_unit_test_libs = \
|
||||||
test_access_storm.la \
|
test_access_storm.la \
|
||||||
test_dep.la \
|
test_dep_active.la \
|
||||||
|
test_device_modes_as_dep.la \
|
||||||
|
test_dep_passive.la \
|
||||||
test_register_access.la \
|
test_register_access.la \
|
||||||
test_register_endianness.la
|
test_register_endianness.la
|
||||||
|
|
||||||
|
@ -24,8 +26,15 @@ AM_LDFLAGS = -module -rpath $(libdir) -avoid-version -no-undefined
|
||||||
test_access_storm_la_SOURCES = test_access_storm.c
|
test_access_storm_la_SOURCES = test_access_storm.c
|
||||||
test_access_storm_la_LIBADD = $(top_builddir)/libnfc/libnfc.la
|
test_access_storm_la_LIBADD = $(top_builddir)/libnfc/libnfc.la
|
||||||
|
|
||||||
test_dep_la_SOURCES = test_dep.c
|
test_dep_active_la_SOURCES = test_dep_active.c
|
||||||
test_dep_la_LIBADD = $(top_builddir)/libnfc/libnfc.la
|
test_dep_active_la_LIBADD = $(top_builddir)/libnfc/libnfc.la \
|
||||||
|
$(top_builddir)/utils/libnfcutils.la
|
||||||
|
|
||||||
|
test_device_modes_as_dep_la_SOURCES = test_device_modes_as_dep.c
|
||||||
|
test_device_modes_as_dep_la_LIBADD = $(top_builddir)/libnfc/libnfc.la
|
||||||
|
|
||||||
|
test_dep_passive_la_SOURCES = test_dep_passive.c
|
||||||
|
test_dep_passive_la_LIBADD = $(top_builddir)/libnfc/libnfc.la
|
||||||
|
|
||||||
test_register_access_la_SOURCES = test_register_access.c
|
test_register_access_la_SOURCES = test_register_access.c
|
||||||
test_register_access_la_LIBADD = $(top_builddir)/libnfc/libnfc.la
|
test_register_access_la_LIBADD = $(top_builddir)/libnfc/libnfc.la
|
||||||
|
|
|
@ -14,40 +14,42 @@ void
|
||||||
test_access_storm (void)
|
test_access_storm (void)
|
||||||
{
|
{
|
||||||
int n = NTESTS;
|
int n = NTESTS;
|
||||||
nfc_device_desc_t devices[MAX_DEVICE_COUNT];
|
nfc_connstring connstrings[MAX_DEVICE_COUNT];
|
||||||
size_t device_count, ref_device_count, target_count;
|
int res = 0;
|
||||||
bool res;
|
|
||||||
|
|
||||||
nfc_list_devices (devices, MAX_DEVICE_COUNT, &ref_device_count);
|
nfc_init (NULL);
|
||||||
|
|
||||||
|
size_t ref_device_count = nfc_list_devices (NULL, connstrings, MAX_DEVICE_COUNT);
|
||||||
if (!ref_device_count)
|
if (!ref_device_count)
|
||||||
cut_omit ("No NFC device found");
|
cut_omit ("No NFC device found");
|
||||||
|
|
||||||
while (n) {
|
while (n) {
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
nfc_list_devices (devices, MAX_DEVICE_COUNT, &device_count);
|
size_t device_count = nfc_list_devices (NULL, connstrings, MAX_DEVICE_COUNT);
|
||||||
cut_assert_equal_int (ref_device_count, device_count, cut_message ("device count"));
|
cut_assert_equal_int (ref_device_count, device_count, cut_message ("device count"));
|
||||||
|
|
||||||
for (i = 0; i < device_count; i++) {
|
for (i = 0; i < device_count; i++) {
|
||||||
nfc_device_t *device;
|
nfc_device *device;
|
||||||
nfc_target_t ant[MAX_TARGET_COUNT];
|
nfc_target ant[MAX_TARGET_COUNT];
|
||||||
|
|
||||||
device = nfc_connect (&(devices[i]));
|
device = nfc_open (NULL, connstrings[i]);
|
||||||
cut_assert_not_null (device, cut_message ("nfc_connect"));
|
cut_assert_not_null (device, cut_message ("nfc_open"));
|
||||||
|
|
||||||
res = nfc_initiator_init(device);
|
res = nfc_initiator_init(device);
|
||||||
cut_assert_true (res, cut_message ("nfc_initiator_init"));
|
cut_assert_equal_int (0, res, cut_message ("nfc_initiator_init"));
|
||||||
|
|
||||||
const nfc_modulation_t nm = {
|
const nfc_modulation nm = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
.nbr = NBR_106,
|
.nbr = NBR_106,
|
||||||
};
|
};
|
||||||
res = nfc_initiator_list_passive_targets(device, nm, ant, MAX_TARGET_COUNT, &target_count);
|
res = nfc_initiator_list_passive_targets(device, nm, ant, MAX_TARGET_COUNT);
|
||||||
cut_assert_true (res, cut_message ("nfc_initiator_list_passive_targets"));
|
cut_assert_operator_int (res, >=, 0, cut_message ("nfc_initiator_list_passive_targets"));
|
||||||
|
|
||||||
nfc_disconnect (device);
|
nfc_close (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
|
nfc_exit (NULL);
|
||||||
}
|
}
|
||||||
|
|
178
test/test_dep.c
178
test/test_dep.c
|
@ -1,178 +0,0 @@
|
||||||
#include <cutter.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "nfc/nfc.h"
|
|
||||||
|
|
||||||
#define INITIATOR 0
|
|
||||||
#define TARGET 1
|
|
||||||
|
|
||||||
pthread_t threads[2];
|
|
||||||
nfc_device_desc_t device_descriptions[2];
|
|
||||||
nfc_device_t *devices[2];
|
|
||||||
intptr_t result[2];
|
|
||||||
|
|
||||||
void
|
|
||||||
abort_test_by_keypress (int sig)
|
|
||||||
{
|
|
||||||
(void) sig;
|
|
||||||
printf ("\033[0;1;31mSIGINT\033[0m");
|
|
||||||
|
|
||||||
nfc_abort_command (devices[INITIATOR]);
|
|
||||||
nfc_abort_command (devices[TARGET]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cut_setup (void)
|
|
||||||
{
|
|
||||||
size_t n;
|
|
||||||
|
|
||||||
nfc_list_devices (device_descriptions, 2, &n);
|
|
||||||
if (n < 2) {
|
|
||||||
cut_omit ("At least two NFC devices must be plugged-in to run this test");
|
|
||||||
}
|
|
||||||
|
|
||||||
devices[TARGET] = nfc_connect (&device_descriptions[TARGET]);
|
|
||||||
devices[INITIATOR] = nfc_connect (&device_descriptions[INITIATOR]);
|
|
||||||
|
|
||||||
signal (SIGINT, abort_test_by_keypress);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cut_teardown (void)
|
|
||||||
{
|
|
||||||
nfc_disconnect (devices[TARGET]);
|
|
||||||
nfc_disconnect (devices[INITIATOR]);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct thread_data {
|
|
||||||
nfc_device_t *device;
|
|
||||||
void *cut_test_context;
|
|
||||||
};
|
|
||||||
|
|
||||||
void *
|
|
||||||
target_thread (void *arg)
|
|
||||||
{
|
|
||||||
intptr_t thread_res = 0;
|
|
||||||
// nfc_device_t *device = ((struct thread_data *) arg)->device;
|
|
||||||
cut_set_current_test_context (((struct thread_data *) arg)->cut_test_context);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
nfc_target_t nt = {
|
|
||||||
.nm = {
|
|
||||||
.nmt = NMT_DEP,
|
|
||||||
.nbr = NBR_UNDEFINED
|
|
||||||
},
|
|
||||||
.nti = {
|
|
||||||
.ndi = {
|
|
||||||
.abtNFCID3 = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA },
|
|
||||||
.szGB = 4,
|
|
||||||
.abtGB = { 0x12, 0x34, 0x56, 0x78 },
|
|
||||||
.ndm = NDM_UNDEFINED,
|
|
||||||
/* These bytes are not used by nfc_target_init: the chip will provide them automatically to the initiator */
|
|
||||||
.btDID = 0x00,
|
|
||||||
.btBS = 0x00,
|
|
||||||
.btBR = 0x00,
|
|
||||||
.btTO = 0x00,
|
|
||||||
.btPP = 0x01,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
byte_t abtRx[1024];
|
|
||||||
size_t szRx = sizeof (abtRx);
|
|
||||||
bool res = nfc_target_init (device, &nt, abtRx, &szRx);
|
|
||||||
// cut_assert_true (res, cut_message ("Can't initialize NFC device as target"));
|
|
||||||
|
|
||||||
byte_t abtAtrRes[] = "\x11\xd4\x00\x01\xfe\x12\x34\x56\x78\x90\x12\x00\x00\x00\x00\x00\x00";
|
|
||||||
// cut_assert_equal_memory (abtAtrRes, sizeof (abtAtrRes) - 1, abtRx, szRx, cut_message ("Invalid received ATR_RES"));
|
|
||||||
|
|
||||||
res = nfc_target_receive_bytes (device, abtRx, &szRx);
|
|
||||||
// cut_assert_true (res, cut_message ("Can't receive bytes from initiator"));
|
|
||||||
|
|
||||||
byte_t abtAttRx[] = "Hello DEP target!";
|
|
||||||
// cut_assert_equal_memory (abtAttRx, sizeof (abtAttRx), abtRx, szRx, cut_message ("Invalid received data"));
|
|
||||||
|
|
||||||
byte_t abtTx[] = "Hello DEP initiator!";
|
|
||||||
res = nfc_target_send_bytes (device, abtTx, sizeof(abtTx));
|
|
||||||
// cut_assert_true (res, cut_message ("Can't send bytes to initiator"));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (void *) thread_res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
initiator_thread (void *arg)
|
|
||||||
{
|
|
||||||
intptr_t thread_res = 0;
|
|
||||||
// nfc_device_t *device = ((struct thread_data *) arg)->device;
|
|
||||||
cut_set_current_test_context (((struct thread_data *) arg)->cut_test_context);
|
|
||||||
|
|
||||||
cut_fail("plop");
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
* Wait some time for the other thread to initialise NFC device as target
|
|
||||||
*/
|
|
||||||
sleep (1);
|
|
||||||
printf ("====================================\n");
|
|
||||||
printf ("Activating initiator...\n");
|
|
||||||
|
|
||||||
bool res = nfc_initiator_init (device);
|
|
||||||
// cut_assert_true (res, cut_message ("Can't initialize NFC device as initiator"));
|
|
||||||
|
|
||||||
nfc_target_t nt;
|
|
||||||
|
|
||||||
// Passive mode / 212Kbps
|
|
||||||
res = nfc_initiator_select_dep_target (device, NDM_PASSIVE, NBR_212, NULL, &nt);
|
|
||||||
// cut_assert_true (res, cut_message ("Can't select any DEP target"));
|
|
||||||
// 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"));
|
|
||||||
// cut_assert_equal_int (NDM_PASSIVE, nt.nti.ndi.ndm, cut_message ("Invalid target DEP mode"));
|
|
||||||
// cut_assert_equal_memory ("\x12\x34\x56\x78", 4, nt.nti.ndi.abtGB, nt.nti.ndi.szGB, cut_message ("Invalid target general bytes"));
|
|
||||||
|
|
||||||
byte_t abtTx[] = "Hello DEP target!";
|
|
||||||
byte_t abtRx[1024];
|
|
||||||
size_t szRx = sizeof (abtRx);
|
|
||||||
res = nfc_initiator_transceive_bytes (device, abtTx, sizeof (abtTx), abtRx, &szRx);
|
|
||||||
// cut_assert_true (res, cut_message ("Can't transceive bytes to target"));
|
|
||||||
|
|
||||||
byte_t abtAttRx[] = "Hello DEP initiator!";
|
|
||||||
// cut_assert_equal_memory (abtAttRx, sizeof (abtAttRx), abtRx, szRx, cut_message ("Invalid received data"));
|
|
||||||
|
|
||||||
res = nfc_initiator_deselect_target (device);
|
|
||||||
// cut_assert_true (res, cut_message ("Can't deselect target"));
|
|
||||||
#endif
|
|
||||||
return (void *) thread_res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
test_dep (void)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
|
|
||||||
CutTestContext *test_context = cut_get_current_test_context ();
|
|
||||||
struct thread_data target_data = {
|
|
||||||
.device = devices[TARGET],
|
|
||||||
.cut_test_context = test_context,
|
|
||||||
};
|
|
||||||
if ((res = pthread_create (&(threads[TARGET]), NULL, target_thread, &target_data)))
|
|
||||||
cut_fail ("pthread_create() returned %d", res);
|
|
||||||
|
|
||||||
struct thread_data initiator_data = {
|
|
||||||
.device = devices[INITIATOR],
|
|
||||||
.cut_test_context = test_context,
|
|
||||||
};
|
|
||||||
if ((res = pthread_create (&(threads[INITIATOR]), NULL, initiator_thread, &initiator_data)))
|
|
||||||
cut_fail ("pthread_create() returned %d", res);
|
|
||||||
|
|
||||||
if ((res = pthread_join (threads[INITIATOR], (void *) &result[INITIATOR])))
|
|
||||||
cut_fail ("pthread_join() returned %d", res);
|
|
||||||
if ((res = pthread_join (threads[TARGET], (void *) &result[TARGET])))
|
|
||||||
cut_fail ("pthread_join() returned %d", res);
|
|
||||||
|
|
||||||
cut_assert_equal_int (0, result[INITIATOR], cut_message ("Unexpected initiator return code"));
|
|
||||||
cut_assert_equal_int (0, result[TARGET], cut_message ("Unexpected target return code"));
|
|
||||||
}
|
|
185
test/test_dep_active.c
Normal file
185
test/test_dep_active.c
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
#include <cutter.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "nfc/nfc.h"
|
||||||
|
#include "../utils/nfc-utils.h"
|
||||||
|
|
||||||
|
#define INITIATOR 0
|
||||||
|
#define TARGET 1
|
||||||
|
|
||||||
|
pthread_t threads[2];
|
||||||
|
nfc_connstring connstrings[2];
|
||||||
|
nfc_device *devices[2];
|
||||||
|
intptr_t result[2];
|
||||||
|
|
||||||
|
void
|
||||||
|
abort_test_by_keypress (int sig)
|
||||||
|
{
|
||||||
|
(void) sig;
|
||||||
|
printf ("\033[0;1;31mSIGINT\033[0m");
|
||||||
|
|
||||||
|
nfc_abort_command (devices[INITIATOR]);
|
||||||
|
nfc_abort_command (devices[TARGET]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cut_setup (void)
|
||||||
|
{
|
||||||
|
size_t n = nfc_list_devices (NULL, connstrings, 2);
|
||||||
|
if (n < 2) {
|
||||||
|
cut_omit ("At least two NFC devices must be plugged-in to run this test");
|
||||||
|
}
|
||||||
|
nfc_init (NULL);
|
||||||
|
devices[TARGET] = nfc_open (NULL, connstrings[TARGET]);
|
||||||
|
devices[INITIATOR] = nfc_open (NULL, connstrings[INITIATOR]);
|
||||||
|
|
||||||
|
signal (SIGINT, abort_test_by_keypress);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cut_teardown (void)
|
||||||
|
{
|
||||||
|
nfc_close (devices[TARGET]);
|
||||||
|
nfc_close (devices[INITIATOR]);
|
||||||
|
nfc_exit (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct thread_data {
|
||||||
|
nfc_device *device;
|
||||||
|
void *cut_test_context;
|
||||||
|
nfc_baud_rate nbr;
|
||||||
|
};
|
||||||
|
|
||||||
|
void *
|
||||||
|
target_thread (void *arg)
|
||||||
|
{
|
||||||
|
intptr_t thread_res = 0;
|
||||||
|
nfc_device *device = ((struct thread_data *) arg)->device;
|
||||||
|
cut_set_current_test_context (((struct thread_data *) arg)->cut_test_context);
|
||||||
|
|
||||||
|
printf ("=========== TARGET %s =========\n", nfc_device_get_name (device));
|
||||||
|
nfc_target nt = {
|
||||||
|
.nm = {
|
||||||
|
.nmt = NMT_DEP,
|
||||||
|
.nbr = NBR_UNDEFINED
|
||||||
|
},
|
||||||
|
.nti = {
|
||||||
|
.ndi = {
|
||||||
|
.abtNFCID3 = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA },
|
||||||
|
.szGB = 4,
|
||||||
|
.abtGB = { 0x12, 0x34, 0x56, 0x78 },
|
||||||
|
.ndm = NDM_ACTIVE,
|
||||||
|
/* These bytes are not used by nfc_target_init: the chip will provide them automatically to the initiator */
|
||||||
|
.btDID = 0x00,
|
||||||
|
.btBS = 0x00,
|
||||||
|
.btBR = 0x00,
|
||||||
|
.btTO = 0x00,
|
||||||
|
.btPP = 0x01,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t abtRx[1024];
|
||||||
|
size_t szRx = sizeof (abtRx);
|
||||||
|
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)));
|
||||||
|
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)));
|
||||||
|
szRx = (size_t) res;
|
||||||
|
const uint8_t abtAttRx[] = "Hello DEP target!";
|
||||||
|
cut_assert_equal_memory (abtAttRx, sizeof (abtAttRx), abtRx, szRx, 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)));
|
||||||
|
if (res <= 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
return (void *) thread_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
initiator_thread (void *arg)
|
||||||
|
{
|
||||||
|
intptr_t thread_res = 0;
|
||||||
|
nfc_device *device = ((struct thread_data *) arg)->device;
|
||||||
|
cut_set_current_test_context (((struct thread_data *) arg)->cut_test_context);
|
||||||
|
nfc_baud_rate nbr = (((struct thread_data *) arg)->nbr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait some time for the other thread to initialise NFC device as target
|
||||||
|
*/
|
||||||
|
sleep (1);
|
||||||
|
printf ("=========== INITIATOR %s =========\n", nfc_device_get_name (device));
|
||||||
|
int res = nfc_initiator_init (device);
|
||||||
|
cut_assert_equal_int (0, res, cut_message ("Can't initialize NFC device as initiator: %s", nfc_strerror (device)));
|
||||||
|
if (res < 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
nfc_target nt;
|
||||||
|
|
||||||
|
// 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_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"));
|
||||||
|
cut_assert_equal_int (NDM_ACTIVE, nt.nti.ndi.ndm, cut_message ("Invalid target DEP mode"));
|
||||||
|
cut_assert_equal_memory ("\x12\x34\x56\x78", 4, nt.nti.ndi.abtGB, nt.nti.ndi.szGB, cut_message ("Invalid target general bytes"));
|
||||||
|
if (res <= 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
const uint8_t abtTx[] = "Hello DEP target!";
|
||||||
|
uint8_t abtRx[1024];
|
||||||
|
size_t szRx = sizeof (abtRx);
|
||||||
|
res = nfc_initiator_transceive_bytes (device, abtTx, sizeof (abtTx), abtRx, &szRx, 5000);
|
||||||
|
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, szRx, 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)));
|
||||||
|
if (res < 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
return (void *) thread_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_dep (void)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
nfc_baud_rate nbrs[3] = { NBR_106, NBR_212, NBR_424};
|
||||||
|
|
||||||
|
CutTestContext *test_context = cut_get_current_test_context ();
|
||||||
|
struct thread_data target_data = {
|
||||||
|
.device = devices[TARGET],
|
||||||
|
.cut_test_context = test_context,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct thread_data initiator_data = {
|
||||||
|
.device = devices[INITIATOR],
|
||||||
|
.cut_test_context = test_context,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
initiator_data.nbr = nbrs[i];
|
||||||
|
|
||||||
|
if ((res = pthread_create (&(threads[TARGET]), NULL, target_thread, &target_data)))
|
||||||
|
cut_fail ("pthread_create() returned %d", res);
|
||||||
|
if ((res = pthread_create (&(threads[INITIATOR]), NULL, initiator_thread, &initiator_data)))
|
||||||
|
cut_fail ("pthread_create() returned %d", res);
|
||||||
|
|
||||||
|
if ((res = pthread_join (threads[INITIATOR], (void *) &result[INITIATOR])))
|
||||||
|
cut_fail ("pthread_join() returned %d", res);
|
||||||
|
if ((res = pthread_join (threads[TARGET], (void *) &result[TARGET])))
|
||||||
|
cut_fail ("pthread_join() returned %d", res);
|
||||||
|
|
||||||
|
cut_assert_equal_int (0, result[INITIATOR], cut_message ("Unexpected initiator return code"));
|
||||||
|
cut_assert_equal_int (0, result[TARGET], cut_message ("Unexpected target return code"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
282
test/test_dep_passive.c
Normal file
282
test/test_dep_passive.c
Normal file
|
@ -0,0 +1,282 @@
|
||||||
|
#include <cutter.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "nfc/nfc.h"
|
||||||
|
|
||||||
|
#define INITIATOR 0
|
||||||
|
#define TARGET 1
|
||||||
|
|
||||||
|
pthread_t threads[2];
|
||||||
|
nfc_connstring connstrings[2];
|
||||||
|
nfc_device *devices[2];
|
||||||
|
intptr_t result[2];
|
||||||
|
|
||||||
|
void
|
||||||
|
abort_test_by_keypress (int sig)
|
||||||
|
{
|
||||||
|
(void) sig;
|
||||||
|
printf ("\033[0;1;31mSIGINT\033[0m");
|
||||||
|
|
||||||
|
nfc_abort_command (devices[INITIATOR]);
|
||||||
|
nfc_abort_command (devices[TARGET]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cut_setup (void)
|
||||||
|
{
|
||||||
|
size_t n = nfc_list_devices (NULL, connstrings, 2);
|
||||||
|
if (n < 2) {
|
||||||
|
cut_omit ("At least two NFC devices must be plugged-in to run this test");
|
||||||
|
}
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
devices[TARGET] = nfc_open (NULL, connstrings[TARGET]);
|
||||||
|
devices[INITIATOR] = nfc_open (NULL, connstrings[INITIATOR]);
|
||||||
|
|
||||||
|
signal (SIGINT, abort_test_by_keypress);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cut_teardown (void)
|
||||||
|
{
|
||||||
|
nfc_close (devices[TARGET]);
|
||||||
|
nfc_close (devices[INITIATOR]);
|
||||||
|
nfc_exit (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct thread_data {
|
||||||
|
nfc_device *device;
|
||||||
|
void *cut_test_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
void *
|
||||||
|
target_thread (void *arg)
|
||||||
|
{
|
||||||
|
intptr_t thread_res = 0;
|
||||||
|
nfc_device *device = ((struct thread_data *) arg)->device;
|
||||||
|
cut_set_current_test_context (((struct thread_data *) arg)->cut_test_context);
|
||||||
|
|
||||||
|
printf ("=========== TARGET %s =========\n", nfc_device_get_name (device));
|
||||||
|
nfc_target nt = {
|
||||||
|
.nm = {
|
||||||
|
.nmt = NMT_DEP,
|
||||||
|
.nbr = NBR_UNDEFINED
|
||||||
|
},
|
||||||
|
.nti = {
|
||||||
|
.ndi = {
|
||||||
|
.abtNFCID3 = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA },
|
||||||
|
.szGB = 4,
|
||||||
|
.abtGB = { 0x12, 0x34, 0x56, 0x78 },
|
||||||
|
.ndm = NDM_PASSIVE,
|
||||||
|
/* These bytes are not used by nfc_target_init: the chip will provide them automatically to the initiator */
|
||||||
|
.btDID = 0x00,
|
||||||
|
.btBS = 0x00,
|
||||||
|
.btBR = 0x00,
|
||||||
|
.btTO = 0x00,
|
||||||
|
.btPP = 0x01,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
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)));
|
||||||
|
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)));
|
||||||
|
szRx = (size_t) res;
|
||||||
|
|
||||||
|
const uint8_t abtAttRx[] = "Hello DEP target!";
|
||||||
|
cut_assert_equal_memory (abtAttRx, sizeof (abtAttRx), abtRx, szRx, 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)));
|
||||||
|
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)));
|
||||||
|
szRx = (size_t) res;
|
||||||
|
|
||||||
|
cut_assert_equal_memory (abtAttRx, sizeof (abtAttRx), abtRx, szRx, 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)));
|
||||||
|
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)));
|
||||||
|
szRx = (size_t) res;
|
||||||
|
|
||||||
|
cut_assert_equal_memory (abtAttRx, sizeof (abtAttRx), abtRx, szRx, 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)));
|
||||||
|
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)));
|
||||||
|
szRx = (size_t) res;
|
||||||
|
|
||||||
|
cut_assert_equal_memory (abtAttRx, sizeof (abtAttRx), abtRx, szRx, 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)));
|
||||||
|
if (res <= 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
return (void *) thread_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
initiator_thread (void *arg)
|
||||||
|
{
|
||||||
|
intptr_t thread_res = 0;
|
||||||
|
nfc_device *device = ((struct thread_data *) arg)->device;
|
||||||
|
cut_set_current_test_context (((struct thread_data *) arg)->cut_test_context);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait some time for the other thread to initialise NFC device as target
|
||||||
|
*/
|
||||||
|
sleep (1);
|
||||||
|
printf ("=========== INITIATOR %s =========\n", nfc_device_get_name (device));
|
||||||
|
|
||||||
|
int res = nfc_initiator_init (device);
|
||||||
|
cut_assert_equal_int (0, res, cut_message ("Can't initialize NFC device as initiator: %s", nfc_strerror (device)));
|
||||||
|
if (res < 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
nfc_target nt;
|
||||||
|
|
||||||
|
// 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_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"));
|
||||||
|
cut_assert_equal_int (NDM_PASSIVE, nt.nti.ndi.ndm, cut_message ("Invalid target DEP mode"));
|
||||||
|
cut_assert_equal_memory ("\x12\x34\x56\x78", 4, nt.nti.ndi.abtGB, nt.nti.ndi.szGB, cut_message ("Invalid target general bytes"));
|
||||||
|
if (res <= 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
const uint8_t abtTx[] = "Hello DEP target!";
|
||||||
|
uint8_t abtRx[1024];
|
||||||
|
size_t szRx = sizeof (abtRx);
|
||||||
|
res = nfc_initiator_transceive_bytes (device, abtTx, sizeof (abtTx), abtRx, &szRx, 500);
|
||||||
|
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, szRx, 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)));
|
||||||
|
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_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"));
|
||||||
|
cut_assert_equal_int (NDM_PASSIVE, nt.nti.ndi.ndm, cut_message ("Invalid target DEP mode"));
|
||||||
|
cut_assert_equal_memory ("\x12\x34\x56\x78", 4, nt.nti.ndi.abtGB, nt.nti.ndi.szGB, cut_message ("Invalid target general bytes"));
|
||||||
|
if (res <= 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
szRx = sizeof (abtRx);
|
||||||
|
res = nfc_initiator_transceive_bytes (device, abtTx, sizeof (abtTx), abtRx, &szRx, 1000);
|
||||||
|
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, szRx, 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)));
|
||||||
|
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_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"));
|
||||||
|
cut_assert_equal_int (NDM_PASSIVE, nt.nti.ndi.ndm, cut_message ("Invalid target DEP mode"));
|
||||||
|
cut_assert_equal_memory ("\x12\x34\x56\x78", 4, nt.nti.ndi.abtGB, nt.nti.ndi.szGB, cut_message ("Invalid target general bytes"));
|
||||||
|
if (res <= 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
szRx = sizeof (abtRx);
|
||||||
|
res = nfc_initiator_transceive_bytes (device, abtTx, sizeof (abtTx), abtRx, &szRx, 5000);
|
||||||
|
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, szRx, 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)));
|
||||||
|
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_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"));
|
||||||
|
cut_assert_equal_int (NDM_PASSIVE, nt.nti.ndi.ndm, cut_message ("Invalid target DEP mode"));
|
||||||
|
cut_assert_equal_memory ("\x12\x34\x56\x78", 4, nt.nti.ndi.abtGB, nt.nti.ndi.szGB, cut_message ("Invalid target general bytes"));
|
||||||
|
if (res <= 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
szRx = sizeof (abtRx);
|
||||||
|
res = nfc_initiator_transceive_bytes (device, abtTx, sizeof (abtTx), abtRx, &szRx, 5000);
|
||||||
|
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, szRx, 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)));
|
||||||
|
if (res < 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
return (void *) thread_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_dep (void)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
CutTestContext *test_context = cut_get_current_test_context ();
|
||||||
|
struct thread_data target_data = {
|
||||||
|
.device = devices[TARGET],
|
||||||
|
.cut_test_context = test_context,
|
||||||
|
};
|
||||||
|
if ((res = pthread_create (&(threads[TARGET]), NULL, target_thread, &target_data)))
|
||||||
|
cut_fail ("pthread_create() returned %d", res);
|
||||||
|
|
||||||
|
struct thread_data initiator_data = {
|
||||||
|
.device = devices[INITIATOR],
|
||||||
|
.cut_test_context = test_context,
|
||||||
|
};
|
||||||
|
if ((res = pthread_create (&(threads[INITIATOR]), NULL, initiator_thread, &initiator_data)))
|
||||||
|
cut_fail ("pthread_create() returned %d", res);
|
||||||
|
|
||||||
|
if ((res = pthread_join (threads[INITIATOR], (void *) &result[INITIATOR])))
|
||||||
|
cut_fail ("pthread_join() returned %d", res);
|
||||||
|
if ((res = pthread_join (threads[TARGET], (void *) &result[TARGET])))
|
||||||
|
cut_fail ("pthread_join() returned %d", res);
|
||||||
|
|
||||||
|
cut_assert_equal_int (0, result[INITIATOR], cut_message ("Unexpected initiator return code"));
|
||||||
|
cut_assert_equal_int (0, result[TARGET], cut_message ("Unexpected target return code"));
|
||||||
|
}
|
212
test/test_device_modes_as_dep.c
Normal file
212
test/test_device_modes_as_dep.c
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
#include <cutter.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "nfc/nfc.h"
|
||||||
|
#include "../utils/nfc-utils.h"
|
||||||
|
|
||||||
|
pthread_t threads[2];
|
||||||
|
nfc_connstring connstrings[2];
|
||||||
|
nfc_device *first_device, *second_device;
|
||||||
|
intptr_t result[2];
|
||||||
|
|
||||||
|
void
|
||||||
|
abort_test_by_keypress (int sig)
|
||||||
|
{
|
||||||
|
(void) sig;
|
||||||
|
printf ("\033[0;1;31mSIGINT\033[0m");
|
||||||
|
|
||||||
|
nfc_abort_command (first_device);
|
||||||
|
nfc_abort_command (second_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cut_setup (void)
|
||||||
|
{
|
||||||
|
size_t n = nfc_list_devices (NULL, connstrings, 2);
|
||||||
|
if (n < 2) {
|
||||||
|
cut_omit ("At least two NFC devices must be plugged-in to run this test");
|
||||||
|
}
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
second_device = nfc_open (NULL, connstrings[0]);
|
||||||
|
first_device = nfc_open (NULL, connstrings[1]);
|
||||||
|
|
||||||
|
signal (SIGINT, abort_test_by_keypress);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cut_teardown (void)
|
||||||
|
{
|
||||||
|
nfc_close (second_device);
|
||||||
|
nfc_close (first_device);
|
||||||
|
nfc_exit (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct thread_data {
|
||||||
|
nfc_device *device;
|
||||||
|
void *cut_test_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
void *
|
||||||
|
target_thread (void *arg)
|
||||||
|
{
|
||||||
|
intptr_t thread_res = 0;
|
||||||
|
nfc_device *device = ((struct thread_data *) arg)->device;
|
||||||
|
cut_set_current_test_context (((struct thread_data *) arg)->cut_test_context);
|
||||||
|
|
||||||
|
printf ("=========== TARGET %s =========\n", nfc_device_get_name (device));
|
||||||
|
nfc_target nt;
|
||||||
|
|
||||||
|
uint8_t abtRx[1024];
|
||||||
|
size_t szRx = sizeof (abtRx);
|
||||||
|
|
||||||
|
// 1) nfc_target_init should take target in idle mode
|
||||||
|
int res = nfc_target_init (device, &nt, abtRx, szRx, 500);
|
||||||
|
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
|
||||||
|
nfc_target nt1 = {
|
||||||
|
.nm = {
|
||||||
|
.nmt = NMT_DEP,
|
||||||
|
.nbr = NBR_UNDEFINED
|
||||||
|
},
|
||||||
|
.nti = {
|
||||||
|
.ndi = {
|
||||||
|
.abtNFCID3 = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA },
|
||||||
|
.szGB = 4,
|
||||||
|
.abtGB = { 0x12, 0x34, 0x56, 0x78 },
|
||||||
|
.ndm = NDM_PASSIVE,
|
||||||
|
/* These bytes are not used by nfc_target_init: the chip will provide them automatically to the initiator */
|
||||||
|
.btDID = 0x00,
|
||||||
|
.btBS = 0x00,
|
||||||
|
.btBR = 0x00,
|
||||||
|
.btTO = 0x00,
|
||||||
|
.btPP = 0x01,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
sleep(6);
|
||||||
|
res = nfc_target_init (device, &nt1, abtRx, szRx, 0);
|
||||||
|
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)));
|
||||||
|
szRx = (size_t) res;
|
||||||
|
|
||||||
|
const uint8_t abtAttRx[] = "Hello DEP target!";
|
||||||
|
cut_assert_equal_memory (abtAttRx, sizeof (abtAttRx), abtRx, szRx, 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)));
|
||||||
|
if (res <= 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
// 3) idle mode
|
||||||
|
sleep (1);
|
||||||
|
nfc_idle (device);
|
||||||
|
|
||||||
|
return (void *) thread_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
initiator_thread (void *arg)
|
||||||
|
{
|
||||||
|
intptr_t thread_res = 0;
|
||||||
|
nfc_device *device = ((struct thread_data *) arg)->device;
|
||||||
|
cut_set_current_test_context (((struct thread_data *) arg)->cut_test_context);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait some time for the other thread to initialise NFC device as target
|
||||||
|
*/
|
||||||
|
sleep (5);
|
||||||
|
printf ("=========== INITIATOR %s =========\n", nfc_device_get_name (device));
|
||||||
|
|
||||||
|
int res = nfc_initiator_init (device);
|
||||||
|
cut_assert_equal_int (0, res, cut_message ("Can't initialize NFC device as initiator: %s", nfc_strerror (device)));
|
||||||
|
if (res < 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
// 1) As other device should be in idle mode, nfc_initiator_poll_dep_target should return 0
|
||||||
|
nfc_target nt;
|
||||||
|
res = nfc_initiator_poll_dep_target (device, NDM_PASSIVE, NBR_106, NULL, &nt, 1000);
|
||||||
|
cut_assert_equal_int (0, res, cut_message ("Problem with nfc_idle"));
|
||||||
|
if (res != 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
|
||||||
|
// 2 As other device should be in target mode, nfc_initiator_poll_dep_target should be positive.
|
||||||
|
nfc_target nt1;
|
||||||
|
|
||||||
|
// 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_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"));
|
||||||
|
cut_assert_equal_int (NDM_PASSIVE, nt1.nti.ndi.ndm, cut_message ("Invalid target DEP mode"));
|
||||||
|
cut_assert_equal_memory ("\x12\x34\x56\x78", 4, nt1.nti.ndi.abtGB, nt1.nti.ndi.szGB, cut_message ("Invalid target general bytes"));
|
||||||
|
if (res <= 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
const uint8_t abtTx[] = "Hello DEP target!";
|
||||||
|
uint8_t abtRx[1024];
|
||||||
|
size_t szRx = sizeof (abtRx);
|
||||||
|
res = nfc_initiator_transceive_bytes (device, abtTx, sizeof (abtTx), abtRx, &szRx, 500);
|
||||||
|
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, szRx, 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)));
|
||||||
|
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
|
||||||
|
nfc_target nt2;
|
||||||
|
res = nfc_initiator_poll_dep_target (device, NDM_PASSIVE, NBR_106, NULL, &nt2, 1000);
|
||||||
|
cut_assert_equal_int (0, res, cut_message ("Problem with nfc_idle"));
|
||||||
|
if (res != 0) { thread_res = -1; return (void*) thread_res; }
|
||||||
|
|
||||||
|
return (void *) thread_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_dep_states (void)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
CutTestContext *test_context = cut_get_current_test_context ();
|
||||||
|
struct thread_data target_data = {
|
||||||
|
.device = first_device,
|
||||||
|
.cut_test_context = test_context,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct thread_data initiator_data = {
|
||||||
|
.device = second_device,
|
||||||
|
.cut_test_context = test_context,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
if ((res = pthread_create (&(threads[1]), NULL, target_thread, &target_data)))
|
||||||
|
cut_fail ("pthread_create() returned %d", res);
|
||||||
|
|
||||||
|
if ((res = pthread_create (&(threads[0]), NULL, initiator_thread, &initiator_data)))
|
||||||
|
cut_fail ("pthread_create() returned %d", res);
|
||||||
|
|
||||||
|
if ((res = pthread_join (threads[0], (void *) &result[0])))
|
||||||
|
cut_fail ("pthread_join() returned %d", res);
|
||||||
|
if ((res = pthread_join (threads[1], (void *) &result[1])))
|
||||||
|
cut_fail ("pthread_join() returned %d", res);
|
||||||
|
|
||||||
|
cut_assert_equal_int (0, result[0], cut_message ("Unexpected initiator return code"));
|
||||||
|
cut_assert_equal_int (0, result[1], cut_message ("Unexpected target return code"));
|
||||||
|
|
||||||
|
// initiator --> target, target --> initiator
|
||||||
|
target_data.device = second_device;
|
||||||
|
initiator_data.device = first_device;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,38 +9,40 @@
|
||||||
void
|
void
|
||||||
test_register_endianness (void)
|
test_register_endianness (void)
|
||||||
{
|
{
|
||||||
nfc_device_desc_t devices[MAX_DEVICE_COUNT];
|
nfc_connstring connstrings[MAX_DEVICE_COUNT];
|
||||||
size_t device_count;
|
int res = 0;
|
||||||
bool res;
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
nfc_list_devices (devices, MAX_DEVICE_COUNT, &device_count);
|
size_t device_count = nfc_list_devices (NULL, connstrings, MAX_DEVICE_COUNT);
|
||||||
if (!device_count)
|
if (!device_count)
|
||||||
cut_omit ("No NFC device found");
|
cut_omit ("No NFC device found");
|
||||||
|
|
||||||
nfc_device_t *device;
|
nfc_device *device;
|
||||||
|
|
||||||
device = nfc_connect (&(devices[0]));
|
device = nfc_open (NULL, connstrings[0]);
|
||||||
cut_assert_not_null (device, cut_message ("nfc_connect"));
|
cut_assert_not_null (device, cut_message ("nfc_open"));
|
||||||
|
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
|
|
||||||
/* Set a 0xAA test value in writable register memory to test register access */
|
/* Set a 0xAA test value in writable register memory to test register access */
|
||||||
res = pn53x_write_register (device, PN53X_REG_CIU_TxMode, 0xFF, 0xAA);
|
res = pn53x_write_register (device, PN53X_REG_CIU_TxMode, 0xFF, 0xAA);
|
||||||
cut_assert_true (res, cut_message ("write register value to 0xAA"));
|
cut_assert_equal_int (0, res, cut_message ("write register value to 0xAA"));
|
||||||
|
|
||||||
/* Get test value from register memory */
|
/* Get test value from register memory */
|
||||||
res = pn53x_read_register (device, PN53X_REG_CIU_TxMode, &value);
|
res = pn53x_read_register (device, PN53X_REG_CIU_TxMode, &value);
|
||||||
cut_assert_true (res, cut_message ("read register value"));
|
cut_assert_equal_int (0, res, cut_message ("read register value"));
|
||||||
cut_assert_equal_uint (0xAA, value, cut_message ("check register value"));
|
cut_assert_equal_uint (0xAA, value, cut_message ("check register value"));
|
||||||
|
|
||||||
/* Set a 0x55 test value in writable register memory to test register access */
|
/* Set a 0x55 test value in writable register memory to test register access */
|
||||||
res = pn53x_write_register (device, PN53X_REG_CIU_TxMode, 0xFF, 0x55);
|
res = pn53x_write_register (device, PN53X_REG_CIU_TxMode, 0xFF, 0x55);
|
||||||
cut_assert_true (res, cut_message ("write register value to 0x55"));
|
cut_assert_equal_int (0, res, cut_message ("write register value to 0x55"));
|
||||||
|
|
||||||
/* Get test value from register memory */
|
/* Get test value from register memory */
|
||||||
res = pn53x_read_register (device, PN53X_REG_CIU_TxMode, &value);
|
res = pn53x_read_register (device, PN53X_REG_CIU_TxMode, &value);
|
||||||
cut_assert_true (res, cut_message ("read register value"));
|
cut_assert_equal_int (0, res, cut_message ("read register value"));
|
||||||
cut_assert_equal_uint (0x55, value, cut_message ("check register value"));
|
cut_assert_equal_uint (0x55, value, cut_message ("check register value"));
|
||||||
|
|
||||||
nfc_disconnect (device);
|
nfc_close (device);
|
||||||
|
nfc_exit (NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,28 +10,30 @@
|
||||||
void
|
void
|
||||||
test_register_endianness (void)
|
test_register_endianness (void)
|
||||||
{
|
{
|
||||||
nfc_device_desc_t devices[MAX_DEVICE_COUNT];
|
nfc_connstring connstrings[MAX_DEVICE_COUNT];
|
||||||
size_t device_count;
|
int res = 0;
|
||||||
bool res;
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
nfc_list_devices (devices, MAX_DEVICE_COUNT, &device_count);
|
size_t device_count = nfc_list_devices (NULL, connstrings, MAX_DEVICE_COUNT);
|
||||||
if (!device_count)
|
if (!device_count)
|
||||||
cut_omit ("No NFC device found");
|
cut_omit ("No NFC device found");
|
||||||
|
|
||||||
nfc_device_t *device;
|
nfc_device *device;
|
||||||
|
|
||||||
device = nfc_connect (&(devices[0]));
|
device = nfc_open (NULL, connstrings[0]);
|
||||||
cut_assert_not_null (device, cut_message ("nfc_connect"));
|
cut_assert_not_null (device, cut_message ("nfc_open"));
|
||||||
|
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
|
|
||||||
/* Read valid XRAM memory */
|
/* Read valid XRAM memory */
|
||||||
res = pn53x_read_register (device, 0xF0FF, &value);
|
res = pn53x_read_register (device, 0xF0FF, &value);
|
||||||
cut_assert_true (res, cut_message ("read register 0xF0FF"));
|
cut_assert_equal_int (0, res, cut_message ("read register 0xF0FF"));
|
||||||
|
|
||||||
/* Read invalid SFR register */
|
/* Read invalid SFR register */
|
||||||
res = pn53x_read_register (device, 0xFFF0, &value);
|
res = pn53x_read_register (device, 0xFFF0, &value);
|
||||||
cut_assert_false (res, cut_message ("read register 0xFFF0"));
|
cut_assert_equal_int (0, res, cut_message ("read register 0xFFF0"));
|
||||||
|
|
||||||
nfc_disconnect (device);
|
nfc_close (device);
|
||||||
|
nfc_exit (NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
SET(UTILS-SOURCES nfc-emulate-forum-tag2 nfc-emulate-forum-tag4 nfc-list nfc-relay-picc nfc-mfclassic nfc-mfultralight)
|
SET(UTILS-SOURCES nfc-emulate-forum-tag4 nfc-list nfc-relay-picc nfc-mfclassic nfc-mfultralight)
|
||||||
|
|
||||||
ADD_LIBRARY(nfcutils STATIC
|
ADD_LIBRARY(nfcutils STATIC
|
||||||
nfc-utils.c
|
nfc-utils.c
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
bin_PROGRAMS = \
|
bin_PROGRAMS = \
|
||||||
nfc-emulate-forum-tag2 \
|
|
||||||
nfc-emulate-forum-tag4 \
|
nfc-emulate-forum-tag4 \
|
||||||
nfc-list \
|
nfc-list \
|
||||||
nfc-mfclassic \
|
nfc-mfclassic \
|
||||||
nfc-mfsetuid \
|
nfc-mfsetuid \
|
||||||
nfc-mfultralight \
|
nfc-mfultralight \
|
||||||
|
nfc-probe \
|
||||||
nfc-read-forum-tag3 \
|
nfc-read-forum-tag3 \
|
||||||
nfc-relay-picc
|
nfc-relay-picc
|
||||||
|
|
||||||
|
@ -18,10 +18,6 @@ noinst_LTLIBRARIES = libnfcutils.la
|
||||||
|
|
||||||
libnfcutils_la_SOURCES = nfc-utils.c
|
libnfcutils_la_SOURCES = nfc-utils.c
|
||||||
|
|
||||||
nfc_emulate_forum_tag2_SOURCES = nfc-emulate-forum-tag2.c
|
|
||||||
nfc_emulate_forum_tag2_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
|
||||||
libnfcutils.la
|
|
||||||
|
|
||||||
nfc_emulate_forum_tag4_SOURCES = nfc-emulate-forum-tag4.c
|
nfc_emulate_forum_tag4_SOURCES = nfc-emulate-forum-tag4.c
|
||||||
nfc_emulate_forum_tag4_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
nfc_emulate_forum_tag4_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
||||||
libnfcutils.la
|
libnfcutils.la
|
||||||
|
@ -41,6 +37,10 @@ nfc_mfsetuid_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
||||||
nfc_mfultralight_SOURCES = nfc-mfultralight.c mifare.c mifare.h
|
nfc_mfultralight_SOURCES = nfc-mfultralight.c mifare.c mifare.h
|
||||||
nfc_mfultralight_LDADD = $(top_builddir)/libnfc/libnfc.la
|
nfc_mfultralight_LDADD = $(top_builddir)/libnfc/libnfc.la
|
||||||
|
|
||||||
|
nfc_probe_SOURCES = nfc-probe.c
|
||||||
|
nfc_probe_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
||||||
|
libnfcutils.la
|
||||||
|
|
||||||
nfc_read_forum_tag3_SOURCES = nfc-read-forum-tag3.c
|
nfc_read_forum_tag3_SOURCES = nfc-read-forum-tag3.c
|
||||||
nfc_read_forum_tag3_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
nfc_read_forum_tag3_LDADD = $(top_builddir)/libnfc/libnfc.la \
|
||||||
libnfcutils.la
|
libnfcutils.la
|
||||||
|
@ -57,9 +57,4 @@ dist_man_MANS = \
|
||||||
nfc-mfultralight.1 \
|
nfc-mfultralight.1 \
|
||||||
nfc-relay-picc.1
|
nfc-relay-picc.1
|
||||||
|
|
||||||
if HAS_LOG4C
|
|
||||||
AM_CFLAGS += @log4c_CFLAGS@
|
|
||||||
LIBADD = @log4c_LIBS@
|
|
||||||
endif
|
|
||||||
|
|
||||||
EXTRA_DIST = CMakeLists.txt
|
EXTRA_DIST = CMakeLists.txt
|
||||||
|
|
|
@ -48,13 +48,13 @@
|
||||||
* The MIFARE Classic Specification (http://www.nxp.com/acrobat/other/identification/M001053_MF1ICS50_rev5_3.pdf) explains more about this process.
|
* The MIFARE Classic Specification (http://www.nxp.com/acrobat/other/identification/M001053_MF1ICS50_rev5_3.pdf) explains more about this process.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
nfc_initiator_mifare_cmd (nfc_device_t * pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param * pmp)
|
nfc_initiator_mifare_cmd (nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp)
|
||||||
{
|
{
|
||||||
byte_t abtRx[265];
|
uint8_t abtRx[265];
|
||||||
size_t szRx = sizeof(abtRx);
|
size_t szRx = sizeof(abtRx);
|
||||||
size_t szParamLen;
|
size_t szParamLen;
|
||||||
byte_t abtCmd[265];
|
uint8_t abtCmd[265];
|
||||||
bool bEasyFraming;
|
//bool bEasyFraming;
|
||||||
|
|
||||||
abtCmd[0] = mc; // The MIFARE Classic command
|
abtCmd[0] = mc; // The MIFARE Classic command
|
||||||
abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)
|
abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)
|
||||||
|
@ -69,19 +69,19 @@ nfc_initiator_mifare_cmd (nfc_device_t * pnd, const mifare_cmd mc, const uint8_t
|
||||||
// Authenticate command
|
// Authenticate command
|
||||||
case MC_AUTH_A:
|
case MC_AUTH_A:
|
||||||
case MC_AUTH_B:
|
case MC_AUTH_B:
|
||||||
szParamLen = sizeof (mifare_param_auth);
|
szParamLen = sizeof (struct mifare_param_auth);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Data command
|
// Data command
|
||||||
case MC_WRITE:
|
case MC_WRITE:
|
||||||
szParamLen = sizeof (mifare_param_data);
|
szParamLen = sizeof (struct mifare_param_data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Value command
|
// Value command
|
||||||
case MC_DECREMENT:
|
case MC_DECREMENT:
|
||||||
case MC_INCREMENT:
|
case MC_INCREMENT:
|
||||||
case MC_TRANSFER:
|
case MC_TRANSFER:
|
||||||
szParamLen = sizeof (mifare_param_value);
|
szParamLen = sizeof (struct mifare_param_value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Please fix your code, you never should reach this statement
|
// Please fix your code, you never should reach this statement
|
||||||
|
@ -92,30 +92,34 @@ nfc_initiator_mifare_cmd (nfc_device_t * pnd, const mifare_cmd mc, const uint8_t
|
||||||
|
|
||||||
// When available, copy the parameter bytes
|
// When available, copy the parameter bytes
|
||||||
if (szParamLen)
|
if (szParamLen)
|
||||||
memcpy (abtCmd + 2, (byte_t *) pmp, szParamLen);
|
memcpy (abtCmd + 2, (uint8_t *) pmp, szParamLen);
|
||||||
|
|
||||||
bEasyFraming = pnd->bEasyFraming;
|
// FIXME: Save and restore bEasyFraming
|
||||||
if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) {
|
// bEasyFraming = nfc_device_get_property_bool (pnd, NP_EASY_FRAMING, &bEasyFraming);
|
||||||
nfc_perror (pnd, "nfc_configure");
|
if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, true) < 0) {
|
||||||
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Fire the mifare command
|
// Fire the mifare command
|
||||||
if (!nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRx, NULL)) {
|
int res;
|
||||||
if (pnd->iLastError == EINVRXFRAM) {
|
if ((res = nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRx, -1)) < 0) {
|
||||||
// "Invalid received frame" AKA EINVRXFRAM, usual means we are
|
if (res == NFC_ERFTRANS) {
|
||||||
|
// "Invalid received frame", usual means we are
|
||||||
// authenticated on a sector but the requested MIFARE cmd (read, write)
|
// authenticated on a sector but the requested MIFARE cmd (read, write)
|
||||||
// is not permitted by current acces bytes;
|
// is not permitted by current acces bytes;
|
||||||
// So there is nothing to do here.
|
// So there is nothing to do here.
|
||||||
} else {
|
} else {
|
||||||
nfc_perror (pnd, "nfc_initiator_transceive_bytes");
|
nfc_perror (pnd, "nfc_initiator_transceive_bytes");
|
||||||
}
|
}
|
||||||
nfc_configure (pnd, NDO_EASY_FRAMING, bEasyFraming);
|
// XXX nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!nfc_configure (pnd, NDO_EASY_FRAMING, bEasyFraming)) {
|
/* XXX
|
||||||
nfc_perror (pnd, "nfc_configure");
|
if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming) < 0) {
|
||||||
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// When we have executed a read command, copy the received bytes into the param
|
// When we have executed a read command, copy the received bytes into the param
|
||||||
if (mc == MC_READ) {
|
if (mc == MC_READ) {
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
|
|
||||||
# include <nfc/nfc-types.h>
|
# include <nfc/nfc-types.h>
|
||||||
|
|
||||||
// Compiler directive, set struct alignment to 1 byte_t for compatibility
|
// Compiler directive, set struct alignment to 1 uint8_t for compatibility
|
||||||
# pragma pack(1)
|
# pragma pack(1)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -53,50 +53,50 @@ typedef enum {
|
||||||
} mifare_cmd;
|
} mifare_cmd;
|
||||||
|
|
||||||
// MIFARE command params
|
// MIFARE command params
|
||||||
typedef struct {
|
struct mifare_param_auth {
|
||||||
byte_t abtKey[6];
|
uint8_t abtKey[6];
|
||||||
byte_t abtUid[4];
|
uint8_t abtUid[4];
|
||||||
} mifare_param_auth;
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct mifare_param_data {
|
||||||
byte_t abtData[16];
|
uint8_t abtData[16];
|
||||||
} mifare_param_data;
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct mifare_param_value {
|
||||||
byte_t abtValue[4];
|
uint8_t abtValue[4];
|
||||||
} mifare_param_value;
|
};
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
mifare_param_auth mpa;
|
struct mifare_param_auth mpa;
|
||||||
mifare_param_data mpd;
|
struct mifare_param_data mpd;
|
||||||
mifare_param_value mpv;
|
struct mifare_param_value mpv;
|
||||||
} mifare_param;
|
} mifare_param;
|
||||||
|
|
||||||
// Reset struct alignment to default
|
// Reset struct alignment to default
|
||||||
# pragma pack()
|
# pragma pack()
|
||||||
|
|
||||||
bool nfc_initiator_mifare_cmd (nfc_device_t * pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param * pmp);
|
bool nfc_initiator_mifare_cmd (nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp);
|
||||||
|
|
||||||
// Compiler directive, set struct alignment to 1 byte_t for compatibility
|
// Compiler directive, set struct alignment to 1 uint8_t for compatibility
|
||||||
# pragma pack(1)
|
# pragma pack(1)
|
||||||
|
|
||||||
// MIFARE Classic
|
// MIFARE Classic
|
||||||
typedef struct {
|
typedef struct {
|
||||||
byte_t abtUID[4];
|
uint8_t abtUID[4];
|
||||||
byte_t btBCC;
|
uint8_t btBCC;
|
||||||
byte_t btUnknown;
|
uint8_t btUnknown;
|
||||||
byte_t abtATQA[2];
|
uint8_t abtATQA[2];
|
||||||
byte_t abtUnknown[8];
|
uint8_t abtUnknown[8];
|
||||||
} mifare_classic_block_manufacturer;
|
} mifare_classic_block_manufacturer;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
byte_t abtData[16];
|
uint8_t abtData[16];
|
||||||
} mifare_classic_block_data;
|
} mifare_classic_block_data;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
byte_t abtKeyA[6];
|
uint8_t abtKeyA[6];
|
||||||
byte_t abtAccessBits[4];
|
uint8_t abtAccessBits[4];
|
||||||
byte_t abtKeyB[6];
|
uint8_t abtKeyB[6];
|
||||||
} mifare_classic_block_trailer;
|
} mifare_classic_block_trailer;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
|
@ -111,17 +111,17 @@ typedef struct {
|
||||||
|
|
||||||
// MIFARE Ultralight
|
// MIFARE Ultralight
|
||||||
typedef struct {
|
typedef struct {
|
||||||
byte_t sn0[3];
|
uint8_t sn0[3];
|
||||||
byte_t btBCC0;
|
uint8_t btBCC0;
|
||||||
byte_t sn1[4];
|
uint8_t sn1[4];
|
||||||
byte_t btBCC1;
|
uint8_t btBCC1;
|
||||||
byte_t internal;
|
uint8_t internal;
|
||||||
byte_t lock[2];
|
uint8_t lock[2];
|
||||||
byte_t otp[4];
|
uint8_t otp[4];
|
||||||
} mifareul_block_manufacturer;
|
} mifareul_block_manufacturer;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
byte_t abtData[16];
|
uint8_t abtData[16];
|
||||||
} mifareul_block_data;
|
} mifareul_block_data;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
|
|
||||||
#include "nfc-utils.h"
|
#include "nfc-utils.h"
|
||||||
|
|
||||||
static nfc_device_t *pnd;
|
static nfc_device *pnd;
|
||||||
static bool quiet_output = false;
|
static bool quiet_output = false;
|
||||||
|
|
||||||
#define SYMBOL_PARAM_fISO14443_4_PICC 0x20
|
#define SYMBOL_PARAM_fISO14443_4_PICC 0x20
|
||||||
|
@ -113,7 +113,7 @@ uint8_t nfcforum_capability_container[] = {
|
||||||
#define ISO144434A_RATS 0xE0
|
#define ISO144434A_RATS 0xE0
|
||||||
|
|
||||||
int
|
int
|
||||||
nfcforum_tag4_io (struct nfc_emulator *emulator, const byte_t *data_in, const size_t data_in_len, byte_t *data_out, const size_t data_out_len)
|
nfcforum_tag4_io (struct nfc_emulator *emulator, const uint8_t *data_in, const size_t data_in_len, uint8_t *data_out, const size_t data_out_len)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ usage (char *progname)
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
nfc_target_t nt = {
|
nfc_target nt = {
|
||||||
.nm = {
|
.nm = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
.nbr = NBR_UNDEFINED, // Will be updated by nfc_target_init()
|
.nbr = NBR_UNDEFINED, // Will be updated by nfc_target_init()
|
||||||
|
@ -345,31 +345,34 @@ main (int argc, char *argv[])
|
||||||
err (EXIT_FAILURE, "Can't load NDEF file '%s'", argv[1]);
|
err (EXIT_FAILURE, "Can't load NDEF file '%s'", argv[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
// Try to open the NFC reader
|
// Try to open the NFC reader
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_open (NULL, NULL);
|
||||||
|
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
ERR("Unable to connect to NFC device");
|
ERR("Unable to open NFC device");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
signal (SIGINT, stop_emulation);
|
signal (SIGINT, stop_emulation);
|
||||||
|
|
||||||
printf ("Connected to NFC device: %s\n", pnd->acName);
|
printf ("NFC device: %s opened\n", nfc_device_get_name(pnd));
|
||||||
printf ("Emulating NDEF tag now, please touch it with a second NFC device\n");
|
printf ("Emulating NDEF tag now, please touch it with a second NFC device\n");
|
||||||
|
|
||||||
if (0 != nfc_emulate_target (pnd, &emulator)) { // contains already nfc_target_init() call
|
if (0 != nfc_emulate_target (pnd, &emulator)) { // contains already nfc_target_init() call
|
||||||
nfc_perror (pnd, "nfc_emulate_target");
|
nfc_perror (pnd, "nfc_emulate_target");
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_disconnect(pnd);
|
nfc_close(pnd);
|
||||||
|
|
||||||
if (argc == 3) {
|
if (argc == 3) {
|
||||||
if (!(ndef_message_save (argv[2], &nfcforum_tag4_data))) {
|
if (!(ndef_message_save (argv[2], &nfcforum_tag4_data))) {
|
||||||
err (EXIT_FAILURE, "Can't save NDEF file '%s'", argv[2]);
|
err (EXIT_FAILURE, "Can't save NDEF file '%s'", argv[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfc_exit (NULL);
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ This tool displays all available information at selection time.
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.B \-v, \-\-verbose
|
.B \-v
|
||||||
Tells
|
Tells
|
||||||
.I
|
.I
|
||||||
nfc-list
|
nfc-list
|
||||||
|
|
145
utils/nfc-list.c
145
utils/nfc-list.c
|
@ -57,23 +57,38 @@
|
||||||
#define MAX_DEVICE_COUNT 16
|
#define MAX_DEVICE_COUNT 16
|
||||||
#define MAX_TARGET_COUNT 16
|
#define MAX_TARGET_COUNT 16
|
||||||
|
|
||||||
static nfc_device_t *pnd;
|
static nfc_device *pnd;
|
||||||
|
|
||||||
|
void
|
||||||
|
print_usage (const char* progname)
|
||||||
|
{
|
||||||
|
printf ("usage: %s [-v]\n", progname);
|
||||||
|
printf (" -v\t verbose display\n");
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, const char *argv[])
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
|
(void) argc;
|
||||||
const char *acLibnfcVersion;
|
const char *acLibnfcVersion;
|
||||||
size_t szDeviceFound;
|
|
||||||
size_t szTargetFound;
|
|
||||||
size_t i;
|
size_t i;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
nfc_device_desc_t *pnddDevices;
|
int res = 0;
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
// Display libnfc version
|
// Display libnfc version
|
||||||
acLibnfcVersion = nfc_version ();
|
acLibnfcVersion = nfc_version ();
|
||||||
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
|
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
|
||||||
|
if (argc != 1) {
|
||||||
|
if ((argc == 2) && (0 == strcmp ("-v", argv[1]))) {
|
||||||
|
verbose = true;
|
||||||
|
} else {
|
||||||
|
print_usage (argv[0]);
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pnddDevices = parse_args (argc, argv, &szDeviceFound, &verbose);
|
|
||||||
#ifdef HAVE_LIBUSB
|
#ifdef HAVE_LIBUSB
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG
|
||||||
usb_set_debug (4);
|
usb_set_debug (4);
|
||||||
|
@ -82,7 +97,7 @@ main (int argc, const char *argv[])
|
||||||
|
|
||||||
/* Lazy way to open an NFC device */
|
/* Lazy way to open an NFC device */
|
||||||
#if 0
|
#if 0
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_open (NULL, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If specific device is wanted, i.e. an ARYGON device on /dev/ttyUSB0 */
|
/* If specific device is wanted, i.e. an ARYGON device on /dev/ttyUSB0 */
|
||||||
|
@ -91,7 +106,7 @@ main (int argc, const char *argv[])
|
||||||
ndd.pcDriver = "ARYGON";
|
ndd.pcDriver = "ARYGON";
|
||||||
ndd.pcPort = "/dev/ttyUSB0";
|
ndd.pcPort = "/dev/ttyUSB0";
|
||||||
ndd.uiSpeed = 115200;
|
ndd.uiSpeed = 115200;
|
||||||
pnd = nfc_connect (&ndd);
|
pnd = nfc_open (NULL, &ndd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If specific device is wanted, i.e. a SCL3711 on USB */
|
/* If specific device is wanted, i.e. a SCL3711 on USB */
|
||||||
|
@ -99,45 +114,41 @@ main (int argc, const char *argv[])
|
||||||
nfc_device_desc_t ndd;
|
nfc_device_desc_t ndd;
|
||||||
ndd.pcDriver = "PN533_USB";
|
ndd.pcDriver = "PN533_USB";
|
||||||
strcpy(ndd.acDevice, "SCM Micro / SCL3711-NFC&RW");
|
strcpy(ndd.acDevice, "SCM Micro / SCL3711-NFC&RW");
|
||||||
pnd = nfc_connect (&ndd);
|
pnd = nfc_open (NULL, &ndd);
|
||||||
#endif
|
#endif
|
||||||
|
nfc_connstring connstrings[MAX_DEVICE_COUNT];
|
||||||
if (szDeviceFound == 0) {
|
size_t szDeviceFound = nfc_list_devices (NULL, connstrings, MAX_DEVICE_COUNT);
|
||||||
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
|
|
||||||
fprintf (stderr, "malloc() failed\n");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szDeviceFound);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (szDeviceFound == 0) {
|
if (szDeviceFound == 0) {
|
||||||
printf ("No NFC device found.\n");
|
printf ("No NFC device found.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < szDeviceFound; i++) {
|
for (i = 0; i < szDeviceFound; i++) {
|
||||||
nfc_target_t ant[MAX_TARGET_COUNT];
|
nfc_target ant[MAX_TARGET_COUNT];
|
||||||
pnd = nfc_connect (&(pnddDevices[i]));
|
pnd = nfc_open (NULL, connstrings[i]);
|
||||||
|
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
ERR ("%s", "Unable to connect to NFC device.");
|
ERR ("%s", "Unable to open NFC device.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
nfc_initiator_init (pnd);
|
if (nfc_initiator_init (pnd) < 0) {
|
||||||
|
nfc_perror (pnd, "nfc_initiator_init");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
printf ("Connected to NFC device: %s\n", pnd->acName);
|
printf ("NFC device: %s opened\n", nfc_device_get_name (pnd));
|
||||||
|
|
||||||
nfc_modulation_t nm;
|
nfc_modulation nm;
|
||||||
|
|
||||||
nm.nmt = NMT_ISO14443A;
|
nm.nmt = NMT_ISO14443A;
|
||||||
nm.nbr = NBR_106;
|
nm.nbr = NBR_106;
|
||||||
// List ISO14443A targets
|
// List ISO14443A targets
|
||||||
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
|
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
|
||||||
size_t n;
|
int n;
|
||||||
if (verbose || (szTargetFound > 0)) {
|
if (verbose) {
|
||||||
printf ("%d ISO14443A passive target(s) found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
|
printf ("%d ISO14443A passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
|
||||||
}
|
}
|
||||||
for (n = 0; n < szTargetFound; n++) {
|
for (n = 0; n < res; n++) {
|
||||||
print_nfc_iso14443a_info (ant[n].nti.nai, verbose);
|
print_nfc_iso14443a_info (ant[n].nti.nai, verbose);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
@ -146,26 +157,24 @@ main (int argc, const char *argv[])
|
||||||
nm.nmt = NMT_FELICA;
|
nm.nmt = NMT_FELICA;
|
||||||
nm.nbr = NBR_212;
|
nm.nbr = NBR_212;
|
||||||
// List Felica tags
|
// List Felica tags
|
||||||
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
|
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
|
||||||
size_t n;
|
int n;
|
||||||
if (verbose || (szTargetFound > 0)) {
|
if (verbose) {
|
||||||
printf ("%d Felica (212 kbps) passive target(s) found%s\n", (int) szTargetFound,
|
printf ("%d Felica (212 kbps) passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
|
||||||
(szTargetFound == 0) ? ".\n" : ":");
|
|
||||||
}
|
}
|
||||||
for (n = 0; n < szTargetFound; n++) {
|
for (n = 0; n < res; n++) {
|
||||||
print_nfc_felica_info (ant[n].nti.nfi, verbose);
|
print_nfc_felica_info (ant[n].nti.nfi, verbose);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nm.nbr = NBR_424;
|
nm.nbr = NBR_424;
|
||||||
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
|
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
|
||||||
size_t n;
|
int n;
|
||||||
if (verbose || (szTargetFound > 0)) {
|
if (verbose) {
|
||||||
printf ("%d Felica (424 kbps) passive target(s) found%s\n", (int) szTargetFound,
|
printf ("%d Felica (424 kbps) passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
|
||||||
(szTargetFound == 0) ? ".\n" : ":");
|
|
||||||
}
|
}
|
||||||
for (n = 0; n < szTargetFound; n++) {
|
for (n = 0; n < res; n++) {
|
||||||
print_nfc_felica_info (ant[n].nti.nfi, verbose);
|
print_nfc_felica_info (ant[n].nti.nfi, verbose);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
@ -174,12 +183,12 @@ main (int argc, const char *argv[])
|
||||||
nm.nmt = NMT_ISO14443B;
|
nm.nmt = NMT_ISO14443B;
|
||||||
nm.nbr = NBR_106;
|
nm.nbr = NBR_106;
|
||||||
// List ISO14443B targets
|
// List ISO14443B targets
|
||||||
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
|
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
|
||||||
size_t n;
|
int n;
|
||||||
if (verbose || (szTargetFound > 0)) {
|
if (verbose) {
|
||||||
printf ("%d ISO14443B passive target(s) found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
|
printf ("%d ISO14443B passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
|
||||||
}
|
}
|
||||||
for (n = 0; n < szTargetFound; n++) {
|
for (n = 0; n < res; n++) {
|
||||||
print_nfc_iso14443b_info (ant[n].nti.nbi, verbose);
|
print_nfc_iso14443b_info (ant[n].nti.nbi, verbose);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
@ -188,12 +197,12 @@ main (int argc, const char *argv[])
|
||||||
nm.nmt = NMT_ISO14443BI;
|
nm.nmt = NMT_ISO14443BI;
|
||||||
nm.nbr = NBR_106;
|
nm.nbr = NBR_106;
|
||||||
// List ISO14443B' targets
|
// List ISO14443B' targets
|
||||||
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
|
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
|
||||||
size_t n;
|
int n;
|
||||||
if (verbose || (szTargetFound > 0)) {
|
if (verbose) {
|
||||||
printf ("%d ISO14443B' passive target(s) found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
|
printf ("%d ISO14443B' passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
|
||||||
}
|
}
|
||||||
for (n = 0; n < szTargetFound; n++) {
|
for (n = 0; n < res; n++) {
|
||||||
print_nfc_iso14443bi_info (ant[n].nti.nii, verbose);
|
print_nfc_iso14443bi_info (ant[n].nti.nii, verbose);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
@ -202,12 +211,12 @@ main (int argc, const char *argv[])
|
||||||
nm.nmt = NMT_ISO14443B2SR;
|
nm.nmt = NMT_ISO14443B2SR;
|
||||||
nm.nbr = NBR_106;
|
nm.nbr = NBR_106;
|
||||||
// List ISO14443B-2 ST SRx family targets
|
// List ISO14443B-2 ST SRx family targets
|
||||||
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
|
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
|
||||||
size_t n;
|
int n;
|
||||||
if (verbose || (szTargetFound > 0)) {
|
if (verbose) {
|
||||||
printf ("%d ISO14443B-2 ST SRx passive target(s) found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
|
printf ("%d ISO14443B-2 ST SRx passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
|
||||||
}
|
}
|
||||||
for (n = 0; n < szTargetFound; n++) {
|
for (n = 0; n < res; n++) {
|
||||||
print_nfc_iso14443b2sr_info (ant[n].nti.nsi, verbose);
|
print_nfc_iso14443b2sr_info (ant[n].nti.nsi, verbose);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
@ -216,12 +225,12 @@ main (int argc, const char *argv[])
|
||||||
nm.nmt = NMT_ISO14443B2CT;
|
nm.nmt = NMT_ISO14443B2CT;
|
||||||
nm.nbr = NBR_106;
|
nm.nbr = NBR_106;
|
||||||
// List ISO14443B-2 ASK CTx family targets
|
// List ISO14443B-2 ASK CTx family targets
|
||||||
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
|
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
|
||||||
size_t n;
|
int n;
|
||||||
if (verbose || (szTargetFound > 0)) {
|
if (verbose) {
|
||||||
printf ("%d ISO14443B-2 ASK CTx passive target(s) found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
|
printf ("%d ISO14443B-2 ASK CTx passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
|
||||||
}
|
}
|
||||||
for (n = 0; n < szTargetFound; n++) {
|
for (n = 0; n < res; n++) {
|
||||||
print_nfc_iso14443b2ct_info (ant[n].nti.nci, verbose);
|
print_nfc_iso14443b2ct_info (ant[n].nti.nci, verbose);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
@ -230,19 +239,19 @@ main (int argc, const char *argv[])
|
||||||
nm.nmt = NMT_JEWEL;
|
nm.nmt = NMT_JEWEL;
|
||||||
nm.nbr = NBR_106;
|
nm.nbr = NBR_106;
|
||||||
// List Jewel targets
|
// List Jewel targets
|
||||||
if (nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound )) {
|
if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
|
||||||
size_t n;
|
int n;
|
||||||
if (verbose || (szTargetFound > 0)) {
|
if (verbose) {
|
||||||
printf("%d Jewel passive target(s) found%s\n", (int)szTargetFound, (szTargetFound==0)?".\n":":");
|
printf("%d Jewel passive target(s) found%s\n", res, (res == 0)?".\n":":");
|
||||||
}
|
}
|
||||||
for(n=0; n<szTargetFound; n++) {
|
for(n = 0; n < res; n++) {
|
||||||
print_nfc_jewel_info (ant[n].nti.nji, verbose);
|
print_nfc_jewel_info (ant[n].nti.nji, verbose);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (pnddDevices);
|
nfc_exit (NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,15 +52,15 @@
|
||||||
#include "mifare.h"
|
#include "mifare.h"
|
||||||
#include "nfc-utils.h"
|
#include "nfc-utils.h"
|
||||||
|
|
||||||
static nfc_device_t *pnd;
|
static nfc_device *pnd;
|
||||||
static nfc_target_t nt;
|
static nfc_target nt;
|
||||||
static mifare_param mp;
|
static mifare_param mp;
|
||||||
static mifare_classic_tag mtKeys;
|
static mifare_classic_tag mtKeys;
|
||||||
static mifare_classic_tag mtDump;
|
static mifare_classic_tag mtDump;
|
||||||
static bool bUseKeyA;
|
static bool bUseKeyA;
|
||||||
static bool bUseKeyFile;
|
static bool bUseKeyFile;
|
||||||
static uint8_t uiBlocks;
|
static uint8_t uiBlocks;
|
||||||
static byte_t keys[] = {
|
static uint8_t keys[] = {
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7,
|
0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7,
|
||||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5,
|
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5,
|
||||||
|
@ -72,7 +72,7 @@ static byte_t keys[] = {
|
||||||
0xab, 0xcd, 0xef, 0x12, 0x34, 0x56
|
0xab, 0xcd, 0xef, 0x12, 0x34, 0x56
|
||||||
};
|
};
|
||||||
|
|
||||||
static const nfc_modulation_t nmMifare = {
|
static const nfc_modulation nmMifare = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
.nbr = NBR_106,
|
.nbr = NBR_106,
|
||||||
};
|
};
|
||||||
|
@ -81,24 +81,24 @@ static size_t num_keys = sizeof (keys) / 6;
|
||||||
|
|
||||||
#define MAX_FRAME_LEN 264
|
#define MAX_FRAME_LEN 264
|
||||||
|
|
||||||
static byte_t abtRx[MAX_FRAME_LEN];
|
static uint8_t abtRx[MAX_FRAME_LEN];
|
||||||
static size_t szRxBits;
|
static int szRxBits;
|
||||||
static size_t szRx = sizeof(abtRx);
|
static size_t szRx = sizeof(abtRx);
|
||||||
|
|
||||||
byte_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
|
uint8_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
// special unlock command
|
// special unlock command
|
||||||
byte_t abtUnlock1[1] = { 0x40 };
|
uint8_t abtUnlock1[1] = { 0x40 };
|
||||||
byte_t abtUnlock2[1] = { 0x43 };
|
uint8_t abtUnlock2[1] = { 0x43 };
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
|
transmit_bits (const uint8_t *pbtTx, const size_t szTxBits)
|
||||||
{
|
{
|
||||||
// Show transmitted command
|
// Show transmitted command
|
||||||
printf ("Sent bits: ");
|
printf ("Sent bits: ");
|
||||||
print_hex_bits (pbtTx, szTxBits);
|
print_hex_bits (pbtTx, szTxBits);
|
||||||
// Transmit the bit frame command, we don't use the arbitrary parity feature
|
// Transmit the bit frame command, we don't use the arbitrary parity feature
|
||||||
if (!nfc_initiator_transceive_bits (pnd, pbtTx, szTxBits, NULL, abtRx, &szRxBits, NULL))
|
if ((szRxBits = nfc_initiator_transceive_bits (pnd, pbtTx, szTxBits, NULL, abtRx, NULL)) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Show received answer
|
// Show received answer
|
||||||
|
@ -110,13 +110,13 @@ transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
transmit_bytes (const byte_t * pbtTx, const size_t szTx)
|
transmit_bytes (const uint8_t *pbtTx, const size_t szTx)
|
||||||
{
|
{
|
||||||
// Show transmitted command
|
// Show transmitted command
|
||||||
printf ("Sent bits: ");
|
printf ("Sent bits: ");
|
||||||
print_hex (pbtTx, szTx);
|
print_hex (pbtTx, szTx);
|
||||||
// Transmit the command bytes
|
// Transmit the command bytes
|
||||||
if (!nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, &szRx, NULL))
|
if (nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, &szRx, 0) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Show received answer
|
// Show received answer
|
||||||
|
@ -127,7 +127,7 @@ transmit_bytes (const byte_t * pbtTx, const size_t szTx)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_success_or_failure (bool bFailure, uint32_t * uiBlockCounter)
|
print_success_or_failure (bool bFailure, uint32_t *uiBlockCounter)
|
||||||
{
|
{
|
||||||
printf ("%c", (bFailure) ? 'x' : '.');
|
printf ("%c", (bFailure) ? 'x' : '.');
|
||||||
if (uiBlockCounter && !bFailure)
|
if (uiBlockCounter && !bFailure)
|
||||||
|
@ -219,12 +219,12 @@ unlock_card (void)
|
||||||
printf ("Unlocking card\n");
|
printf ("Unlocking card\n");
|
||||||
|
|
||||||
// Configure the CRC
|
// Configure the CRC
|
||||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, false)) {
|
if (nfc_device_set_property_bool (pnd, NP_HANDLE_CRC, false) < 0) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
// Use raw send/receive methods
|
// Use raw send/receive methods
|
||||||
if (!nfc_configure (pnd, NDO_EASY_FRAMING, false)) {
|
if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, false) < 0) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -243,13 +243,13 @@ unlock_card (void)
|
||||||
|
|
||||||
// reset reader
|
// reset reader
|
||||||
// Configure the CRC
|
// Configure the CRC
|
||||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
if (nfc_device_set_property_bool (pnd, NP_HANDLE_CRC, true) < 0) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
// Switch off raw send/receive methods
|
// Switch off raw send/receive methods
|
||||||
if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) {
|
if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, true) < 0) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -280,7 +280,7 @@ read_card (int read_unlocked)
|
||||||
// Show if the readout went well
|
// Show if the readout went well
|
||||||
if (bFailure) {
|
if (bFailure) {
|
||||||
// When a failure occured we need to redo the anti-collision
|
// When a failure occured we need to redo the anti-collision
|
||||||
if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
|
if (nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt) < 0) {
|
||||||
printf ("!\nError: tag was removed\n");
|
printf ("!\nError: tag was removed\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -353,7 +353,7 @@ write_card (int write_block_zero)
|
||||||
// Show if the readout went well
|
// Show if the readout went well
|
||||||
if (bFailure) {
|
if (bFailure) {
|
||||||
// When a failure occured we need to redo the anti-collision
|
// When a failure occured we need to redo the anti-collision
|
||||||
if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
|
if (nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt) < 0) {
|
||||||
printf ("!\nError: tag was removed\n");
|
printf ("!\nError: tag was removed\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -458,7 +458,7 @@ int
|
||||||
main (int argc, const char *argv[])
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
action_t atAction = ACTION_USAGE;
|
action_t atAction = ACTION_USAGE;
|
||||||
byte_t *pbtUID;
|
uint8_t *pbtUID;
|
||||||
FILE *pfKeys = NULL;
|
FILE *pfKeys = NULL;
|
||||||
FILE *pfDump = NULL;
|
FILE *pfDump = NULL;
|
||||||
int unlock= 0;
|
int unlock= 0;
|
||||||
|
@ -537,29 +537,35 @@ main (int argc, const char *argv[])
|
||||||
}
|
}
|
||||||
// printf("Successfully opened required files\n");
|
// printf("Successfully opened required files\n");
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
// Try to open the NFC reader
|
// Try to open the NFC reader
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_open (NULL, NULL);
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
printf ("Error connecting NFC reader\n");
|
printf ("Error opening NFC reader\n");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_initiator_init (pnd);
|
if (nfc_initiator_init (pnd) < 0) {
|
||||||
|
nfc_perror (pnd, "nfc_initiator_init");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
};
|
||||||
|
|
||||||
// Let the reader only try once to find a tag
|
// Let the reader only try once to find a tag
|
||||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
if (nfc_device_set_property_bool (pnd, NP_INFINITE_SELECT, false) < 0) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
// Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance.
|
// Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance.
|
||||||
nfc_configure (pnd, NDO_AUTO_ISO14443_4, false);
|
nfc_device_set_property_bool (pnd, NP_AUTO_ISO14443_4, false);
|
||||||
|
|
||||||
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
printf ("NFC reader: %s opened\n", nfc_device_get_name (pnd));
|
||||||
|
|
||||||
// Try to find a MIFARE Classic tag
|
// Try to find a MIFARE Classic tag
|
||||||
if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
|
if (nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt) < 0) {
|
||||||
printf ("Error: no tag was found\n");
|
printf ("Error: no tag was found\n");
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
// Test if we are dealing with a MIFARE compatible tag
|
// Test if we are dealing with a MIFARE compatible tag
|
||||||
|
@ -571,10 +577,10 @@ main (int argc, const char *argv[])
|
||||||
pbtUID = nt.nti.nai.abtUid;
|
pbtUID = nt.nti.nai.abtUid;
|
||||||
|
|
||||||
if (bUseKeyFile) {
|
if (bUseKeyFile) {
|
||||||
byte_t fileUid[4];
|
uint8_t fileUid[4];
|
||||||
memcpy (fileUid, mtKeys.amb[0].mbm.abtUID, 4);
|
memcpy (fileUid, mtKeys.amb[0].mbm.abtUID, 4);
|
||||||
// Compare if key dump UID is the same as the current tag UID, at least for the first 4 bytes
|
// Compare if key dump UID is the same as the current tag UID, at least for the first 4 bytes
|
||||||
if (memcmp (nt.nti.nai.abtUid, fileUid, 4) != 0) {
|
if (memcmp (pbtUID, fileUid, 4) != 0) {
|
||||||
printf ("Expected MIFARE Classic card with UID starting as: %02x%02x%02x%02x\n",
|
printf ("Expected MIFARE Classic card with UID starting as: %02x%02x%02x%02x\n",
|
||||||
fileUid[0], fileUid[1], fileUid[2], fileUid[3]);
|
fileUid[0], fileUid[1], fileUid[2], fileUid[3]);
|
||||||
}
|
}
|
||||||
|
@ -615,7 +621,7 @@ main (int argc, const char *argv[])
|
||||||
write_card (unlock);
|
write_card (unlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_EXTRACT:{
|
case ACTION_EXTRACT:{
|
||||||
|
@ -658,6 +664,7 @@ main (int argc, const char *argv[])
|
||||||
printf ("Done, all bytes have been extracted!\n");
|
printf ("Done, all bytes have been extracted!\n");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nfc_exit (NULL);
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,39 +56,39 @@
|
||||||
|
|
||||||
#define MAX_FRAME_LEN 264
|
#define MAX_FRAME_LEN 264
|
||||||
|
|
||||||
static byte_t abtRx[MAX_FRAME_LEN];
|
static uint8_t abtRx[MAX_FRAME_LEN];
|
||||||
static size_t szRxBits;
|
static int szRxBits;
|
||||||
static size_t szRx = sizeof(abtRx);
|
static size_t szRx = sizeof(abtRx);
|
||||||
static byte_t abtRawUid[12];
|
static uint8_t abtRawUid[12];
|
||||||
static byte_t abtAtqa[2];
|
static uint8_t abtAtqa[2];
|
||||||
static byte_t abtSak;
|
static uint8_t abtSak;
|
||||||
static byte_t abtAts[MAX_FRAME_LEN];
|
static uint8_t abtAts[MAX_FRAME_LEN];
|
||||||
static byte_t szAts = 0;
|
static uint8_t szAts = 0;
|
||||||
static size_t szCL = 1;//Always start with Cascade Level 1 (CL1)
|
static size_t szCL = 1;//Always start with Cascade Level 1 (CL1)
|
||||||
static nfc_device_t *pnd;
|
static nfc_device *pnd;
|
||||||
|
|
||||||
bool quiet_output = false;
|
bool quiet_output = false;
|
||||||
bool iso_ats_supported = false;
|
bool iso_ats_supported = false;
|
||||||
|
|
||||||
// ISO14443A Anti-Collision Commands
|
// ISO14443A Anti-Collision Commands
|
||||||
byte_t abtReqa[1] = { 0x26 };
|
uint8_t abtReqa[1] = { 0x26 };
|
||||||
byte_t abtSelectAll[2] = { 0x93, 0x20 };
|
uint8_t abtSelectAll[2] = { 0x93, 0x20 };
|
||||||
byte_t abtSelectTag[9] = { 0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t abtSelectTag[9] = { 0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
byte_t abtRats[4] = { 0xe0, 0x50, 0x00, 0x00 };
|
uint8_t abtRats[4] = { 0xe0, 0x50, 0x00, 0x00 };
|
||||||
byte_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
|
uint8_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
|
||||||
#define CASCADE_BIT 0x04
|
#define CASCADE_BIT 0x04
|
||||||
|
|
||||||
// special unlock command
|
// special unlock command
|
||||||
byte_t abtUnlock1[1] = { 0x40 };
|
uint8_t abtUnlock1[1] = { 0x40 };
|
||||||
byte_t abtUnlock2[1] = { 0x43 };
|
uint8_t abtUnlock2[1] = { 0x43 };
|
||||||
byte_t abtWipe[1] = { 0x41 };
|
uint8_t abtWipe[1] = { 0x41 };
|
||||||
byte_t abtWrite[4] = { 0xa0, 0x00, 0x5f, 0xb1 };
|
uint8_t abtWrite[4] = { 0xa0, 0x00, 0x5f, 0xb1 };
|
||||||
byte_t abtData[18] = { 0x01, 0x23, 0x45, 0x67, 0x00, 0x08, 0x04, 0x00, 0x46, 0x59, 0x25, 0x58, 0x49, 0x10, 0x23, 0x02, 0x23, 0xeb };
|
uint8_t abtData[18] = { 0x01, 0x23, 0x45, 0x67, 0x00, 0x08, 0x04, 0x00, 0x46, 0x59, 0x25, 0x58, 0x49, 0x10, 0x23, 0x02, 0x23, 0xeb };
|
||||||
byte_t abtBlank[18] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x36, 0xCC };
|
uint8_t abtBlank[18] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x36, 0xCC };
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
|
transmit_bits (const uint8_t *pbtTx, const size_t szTxBits)
|
||||||
{
|
{
|
||||||
// Show transmitted command
|
// Show transmitted command
|
||||||
if (!quiet_output) {
|
if (!quiet_output) {
|
||||||
|
@ -96,7 +96,7 @@ transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
|
||||||
print_hex_bits (pbtTx, szTxBits);
|
print_hex_bits (pbtTx, szTxBits);
|
||||||
}
|
}
|
||||||
// Transmit the bit frame command, we don't use the arbitrary parity feature
|
// Transmit the bit frame command, we don't use the arbitrary parity feature
|
||||||
if (!nfc_initiator_transceive_bits (pnd, pbtTx, szTxBits, NULL, abtRx, &szRxBits, NULL))
|
if ((szRxBits = nfc_initiator_transceive_bits (pnd, pbtTx, szTxBits, NULL, abtRx, NULL)) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Show received answer
|
// Show received answer
|
||||||
|
@ -110,7 +110,7 @@ transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
transmit_bytes (const byte_t * pbtTx, const size_t szTx)
|
transmit_bytes (const uint8_t *pbtTx, const size_t szTx)
|
||||||
{
|
{
|
||||||
// Show transmitted command
|
// Show transmitted command
|
||||||
if (!quiet_output) {
|
if (!quiet_output) {
|
||||||
|
@ -118,7 +118,7 @@ transmit_bytes (const byte_t * pbtTx, const size_t szTx)
|
||||||
print_hex (pbtTx, szTx);
|
print_hex (pbtTx, szTx);
|
||||||
}
|
}
|
||||||
// Transmit the command bytes
|
// Transmit the command bytes
|
||||||
if (!nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, &szRx, NULL))
|
if (nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, &szRx, 0) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Show received answer
|
// Show received answer
|
||||||
|
@ -177,39 +177,45 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
// Try to open the NFC reader
|
// Try to open the NFC reader
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_open (NULL, NULL);
|
||||||
|
|
||||||
if (!pnd) {
|
if (!pnd) {
|
||||||
printf ("Error connecting NFC reader\n");
|
printf ("Error opening NFC reader\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialise NFC device as "initiator"
|
// Initialise NFC device as "initiator"
|
||||||
nfc_initiator_init (pnd);
|
if (nfc_initiator_init (pnd) < 0) {
|
||||||
|
nfc_perror (pnd, "nfc_initiator_init");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
// Configure the CRC
|
// Configure the CRC
|
||||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, false)) {
|
if (nfc_device_set_property_bool (pnd, NP_HANDLE_CRC, false) < 0) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
// Use raw send/receive methods
|
// Use raw send/receive methods
|
||||||
if (!nfc_configure (pnd, NDO_EASY_FRAMING, false)) {
|
if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, false) < 0) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
// Disable 14443-4 autoswitching
|
// Disable 14443-4 autoswitching
|
||||||
if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, false)) {
|
if (nfc_device_set_property_bool (pnd, NP_AUTO_ISO14443_4, false) < 0) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Connected to NFC reader: %s\n\n", pnd->acName);
|
printf ("NFC reader: %s opened\n", nfc_device_get_name (pnd));
|
||||||
|
|
||||||
// Send the 7 bits request command specified in ISO 14443A (0x26)
|
// Send the 7 bits request command specified in ISO 14443A (0x26)
|
||||||
if (!transmit_bits (abtReqa, 7)) {
|
if (!transmit_bits (abtReqa, 7)) {
|
||||||
printf ("Error: No tag available\n");
|
printf ("Error: No tag available\n");
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
memcpy (abtAtqa, abtRx, 2);
|
memcpy (abtAtqa, abtRx, 2);
|
||||||
|
@ -338,7 +344,7 @@ main (int argc, char *argv[])
|
||||||
transmit_bytes (abtWrite,4);
|
transmit_bytes (abtWrite,4);
|
||||||
transmit_bytes (abtData,18);
|
transmit_bytes (abtData,18);
|
||||||
if(format) {
|
if(format) {
|
||||||
for(i= 3 ; i < 64 ; i += 4) {
|
for(i = 3 ; i < 64 ; i += 4) {
|
||||||
abtWrite[1]= (char) i;
|
abtWrite[1]= (char) i;
|
||||||
iso14443a_crc_append (abtWrite, 2);
|
iso14443a_crc_append (abtWrite, 2);
|
||||||
transmit_bytes (abtWrite,4);
|
transmit_bytes (abtWrite,4);
|
||||||
|
@ -347,6 +353,7 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,13 +51,13 @@
|
||||||
#include "nfc-utils.h"
|
#include "nfc-utils.h"
|
||||||
#include "mifare.h"
|
#include "mifare.h"
|
||||||
|
|
||||||
static nfc_device_t *pnd;
|
static nfc_device *pnd;
|
||||||
static nfc_target_t nt;
|
static nfc_target nt;
|
||||||
static mifare_param mp;
|
static mifare_param mp;
|
||||||
static mifareul_tag mtDump;
|
static mifareul_tag mtDump;
|
||||||
static uint32_t uiBlocks = 0xF;
|
static uint32_t uiBlocks = 0xF;
|
||||||
|
|
||||||
static const nfc_modulation_t nmMifare = {
|
static const nfc_modulation nmMifare = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
.nbr = NBR_106,
|
.nbr = NBR_106,
|
||||||
};
|
};
|
||||||
|
@ -142,7 +142,7 @@ write_card (void)
|
||||||
// Show if the readout went well
|
// Show if the readout went well
|
||||||
if (bFailure) {
|
if (bFailure) {
|
||||||
// When a failure occured we need to redo the anti-collision
|
// When a failure occured we need to redo the anti-collision
|
||||||
if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
|
if (nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt) < 0) {
|
||||||
ERR ("tag was removed");
|
ERR ("tag was removed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -204,34 +204,41 @@ main (int argc, const char *argv[])
|
||||||
}
|
}
|
||||||
DBG ("Successfully opened the dump file\n");
|
DBG ("Successfully opened the dump file\n");
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
// Try to open the NFC device
|
// Try to open the NFC device
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_open (NULL, NULL);
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
ERR ("Error connecting NFC device\n");
|
ERR ("Error opening NFC device\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_initiator_init (pnd);
|
if (nfc_initiator_init (pnd) < 0) {
|
||||||
|
nfc_perror (pnd, "nfc_initiator_init");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
// Let the device only try once to find a tag
|
// Let the device only try once to find a tag
|
||||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
if (nfc_device_set_property_bool (pnd, NP_INFINITE_SELECT, false) < 0) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Connected to NFC device: %s\n", pnd->acName);
|
printf ("NFC device: %s opened\n", nfc_device_get_name (pnd));
|
||||||
|
|
||||||
// Try to find a MIFARE Ultralight tag
|
// Try to find a MIFARE Ultralight tag
|
||||||
if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
|
if (nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt) < 0) {
|
||||||
ERR ("no tag was found\n");
|
ERR ("no tag was found\n");
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// Test if we are dealing with a MIFARE compatible tag
|
// Test if we are dealing with a MIFARE compatible tag
|
||||||
|
|
||||||
if (nt.nti.nai.abtAtqa[1] != 0x44) {
|
if (nt.nti.nai.abtAtqa[1] != 0x44) {
|
||||||
ERR ("tag is not a MIFARE Ultralight card\n");
|
ERR ("tag is not a MIFARE Ultralight card\n");
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
// Get the info from the current tag
|
// Get the info from the current tag
|
||||||
|
@ -262,7 +269,7 @@ main (int argc, const char *argv[])
|
||||||
write_card ();
|
write_card ();
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
|
nfc_exit (NULL);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
115
utils/nfc-probe.c
Normal file
115
utils/nfc-probe.c
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*-
|
||||||
|
* Public platform independent Near Field Communication (NFC) library examples
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009, Roel Verdult
|
||||||
|
* Copyright (C) 2010, Romuald Conty, Romain Tartière
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1) Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2 )Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Note that this license only applies on the examples, NFC library itself is under LGPL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file nfc-probe.c
|
||||||
|
* @brief Lists each available NFC device
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif // HAVE_CONFIG_H
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBUSB
|
||||||
|
# ifdef DEBUG
|
||||||
|
# include <sys/param.h>
|
||||||
|
# include <usb.h>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <nfc/nfc.h>
|
||||||
|
|
||||||
|
#include "nfc-utils.h"
|
||||||
|
|
||||||
|
#define MAX_DEVICE_COUNT 16
|
||||||
|
#define MAX_TARGET_COUNT 16
|
||||||
|
|
||||||
|
static nfc_device *pnd;
|
||||||
|
|
||||||
|
void
|
||||||
|
print_usage (const char* progname)
|
||||||
|
{
|
||||||
|
printf ("usage: %s [-v]\n", progname);
|
||||||
|
printf (" -v\t verbose display\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, const char *argv[])
|
||||||
|
{
|
||||||
|
(void) argc;
|
||||||
|
const char *acLibnfcVersion;
|
||||||
|
size_t i;
|
||||||
|
bool verbose = false;
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
|
// Display libnfc version
|
||||||
|
acLibnfcVersion = nfc_version ();
|
||||||
|
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
|
||||||
|
if (argc != 1) {
|
||||||
|
if ((argc == 2) && (0 == strcmp ("-v", argv[1]))) {
|
||||||
|
verbose = true;
|
||||||
|
} else {
|
||||||
|
print_usage (argv[0]);
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBUSB
|
||||||
|
# ifdef DEBUG
|
||||||
|
usb_set_debug (4);
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nfc_connstring connstrings[MAX_DEVICE_COUNT];
|
||||||
|
size_t szDeviceFound = nfc_list_devices (NULL, connstrings, MAX_DEVICE_COUNT);
|
||||||
|
|
||||||
|
if (szDeviceFound == 0) {
|
||||||
|
printf ("No NFC device found.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("%d NFC device(s) found:\n", szDeviceFound);
|
||||||
|
for (i = 0; i < szDeviceFound; i++) {
|
||||||
|
pnd = nfc_open (NULL, connstrings[i]);
|
||||||
|
if (pnd != NULL) {
|
||||||
|
printf ("- %s:\n %s\n", nfc_device_get_name (pnd), nfc_device_get_connstring (pnd));
|
||||||
|
}
|
||||||
|
nfc_close (pnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
nfc_exit (NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -56,7 +56,7 @@
|
||||||
|
|
||||||
#include "nfc-utils.h"
|
#include "nfc-utils.h"
|
||||||
|
|
||||||
static nfc_device_t *pnd;
|
static nfc_device *pnd;
|
||||||
|
|
||||||
void
|
void
|
||||||
print_usage(char *progname)
|
print_usage(char *progname)
|
||||||
|
@ -76,7 +76,7 @@ void stop_select (int sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
build_felica_frame(const nfc_felica_info_t nfi, const byte_t command, const byte_t* payload, const size_t payload_len, byte_t * frame, size_t * frame_len)
|
build_felica_frame(const nfc_felica_info nfi, const uint8_t command, const uint8_t *payload, const size_t payload_len, uint8_t *frame, size_t *frame_len)
|
||||||
{
|
{
|
||||||
frame[0] = 1 + 1 + 8 + payload_len;
|
frame[0] = 1 + 1 + 8 + payload_len;
|
||||||
*frame_len = frame[0];
|
*frame_len = frame[0];
|
||||||
|
@ -87,9 +87,9 @@ build_felica_frame(const nfc_felica_info_t nfi, const byte_t command, const byte
|
||||||
|
|
||||||
#define CHECK 0x06
|
#define CHECK 0x06
|
||||||
int
|
int
|
||||||
nfc_forum_tag_type3_check (nfc_device_t *pnd, const nfc_target_t nt, const uint16_t block, const uint8_t block_count, byte_t * data, size_t * data_len)
|
nfc_forum_tag_type3_check (nfc_device *pnd, const nfc_target nt, const uint16_t block, const uint8_t block_count, uint8_t *data, size_t *data_len)
|
||||||
{
|
{
|
||||||
byte_t payload[1024] = {
|
uint8_t payload[1024] = {
|
||||||
1, // Services
|
1, // Services
|
||||||
0x0B, 0x00, // NFC Forum Tag Type 3's Service code
|
0x0B, 0x00, // NFC Forum Tag Type 3's Service code
|
||||||
block_count,
|
block_count,
|
||||||
|
@ -97,7 +97,7 @@ nfc_forum_tag_type3_check (nfc_device_t *pnd, const nfc_target_t nt, const uint1
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t payload_len = 1 + 2 + 1;
|
size_t payload_len = 1 + 2 + 1;
|
||||||
for (uint8_t b=0; b<block_count; b++) {
|
for (uint8_t b = 0; b < block_count; b++) {
|
||||||
if (block < 0x100) {
|
if (block < 0x100) {
|
||||||
payload[payload_len++] = 0x80;
|
payload[payload_len++] = 0x80;
|
||||||
payload[payload_len++] = block + b;
|
payload[payload_len++] = block + b;
|
||||||
|
@ -108,18 +108,18 @@ nfc_forum_tag_type3_check (nfc_device_t *pnd, const nfc_target_t nt, const uint1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_t frame[1024];
|
uint8_t frame[1024];
|
||||||
size_t frame_len = sizeof(frame);
|
size_t frame_len = sizeof(frame);
|
||||||
build_felica_frame (nt.nti.nfi, CHECK, payload, payload_len, frame, &frame_len);
|
build_felica_frame (nt.nti.nfi, CHECK, payload, payload_len, frame, &frame_len);
|
||||||
|
|
||||||
byte_t res[1024];
|
uint8_t res[1024];
|
||||||
|
|
||||||
size_t res_len;
|
size_t res_len;
|
||||||
if (!nfc_initiator_transceive_bytes (pnd, frame, frame_len, res, &res_len, NULL)) {
|
if (nfc_initiator_transceive_bytes (pnd, frame, frame_len, res, &res_len, 0) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
const size_t res_overhead = 1 + 1 + 8 + 2; // 1+1+8+2: LEN + CMD + NFCID2 + STATUS
|
const size_t res_overhead = 1 + 1 + 8 + 2; // 1+1+8+2: LEN + CMD + NFCID2 + STATUS
|
||||||
if (res_len<res_overhead) {
|
if (res_len < res_overhead) {
|
||||||
// Not enough data
|
// Not enough data
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -136,8 +136,8 @@ nfc_forum_tag_type3_check (nfc_device_t *pnd, const nfc_target_t nt, const uint1
|
||||||
// NFCID2 does not match
|
// NFCID2 does not match
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
const byte_t status_flag1 = res[10];
|
const uint8_t status_flag1 = res[10];
|
||||||
const byte_t status_flag2 = res[11];
|
const uint8_t status_flag2 = res[11];
|
||||||
if ((status_flag1) || (status_flag2)) {
|
if ((status_flag1) || (status_flag2)) {
|
||||||
// Felica card's error
|
// Felica card's error
|
||||||
fprintf (stderr, "Status bytes: %02x, %02x\n", status_flag1, status_flag2);
|
fprintf (stderr, "Status bytes: %02x, %02x\n", status_flag1, status_flag2);
|
||||||
|
@ -193,43 +193,48 @@ main(int argc, char *argv[])
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfc_init (NULL);
|
||||||
|
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_open (NULL, NULL);
|
||||||
|
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
ERR("Unable to connect to NFC device");
|
ERR("Unable to open NFC device");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (message_stream, "Connected to NFC device: %s\n", pnd->acName);
|
fprintf (message_stream, "NFC device: %s opened\n", nfc_device_get_name (pnd));
|
||||||
|
|
||||||
nfc_modulation_t nm = {
|
nfc_modulation nm = {
|
||||||
.nmt = NMT_FELICA,
|
.nmt = NMT_FELICA,
|
||||||
.nbr = NBR_212,
|
.nbr = NBR_212,
|
||||||
};
|
};
|
||||||
|
|
||||||
signal (SIGINT, stop_select);
|
signal (SIGINT, stop_select);
|
||||||
|
|
||||||
nfc_target_t nt;
|
nfc_target nt;
|
||||||
|
|
||||||
nfc_initiator_init(pnd);
|
if (nfc_initiator_init (pnd) < 0) {
|
||||||
|
nfc_perror (pnd, "nfc_initiator_init");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
fprintf (message_stream, "Place your NFC Forum Tag Type 3 in the field...\n");
|
fprintf (message_stream, "Place your NFC Forum Tag Type 3 in the field...\n");
|
||||||
|
|
||||||
int error = EXIT_SUCCESS;
|
int error = EXIT_SUCCESS;
|
||||||
// Polling payload (SENSF_REQ) must be present (see NFC Digital Protol)
|
// Polling payload (SENSF_REQ) must be present (see NFC Digital Protol)
|
||||||
const byte_t *pbtSensfReq = (byte_t*)"\x00\xff\xff\x01\x00";
|
const uint8_t *pbtSensfReq = (uint8_t*)"\x00\xff\xff\x01\x00";
|
||||||
if (!nfc_initiator_select_passive_target(pnd, nm, pbtSensfReq, 5, &nt)) {
|
if (nfc_initiator_select_passive_target(pnd, nm, pbtSensfReq, 5, &nt) < 0) {
|
||||||
nfc_perror (pnd, "nfc_initiator_select_passive_target");
|
nfc_perror (pnd, "nfc_initiator_select_passive_target");
|
||||||
error = EXIT_FAILURE;
|
error = EXIT_FAILURE;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if System Code equals 0x12fc
|
// Check if System Code equals 0x12fc
|
||||||
const byte_t abtNfcForumSysCode[] = { 0x12, 0xfc };
|
const uint8_t abtNfcForumSysCode[] = { 0x12, 0xfc };
|
||||||
if (0 != memcmp (nt.nti.nfi.abtSysCode, abtNfcForumSysCode, 2)) {
|
if (0 != memcmp (nt.nti.nfi.abtSysCode, abtNfcForumSysCode, 2)) {
|
||||||
// Retry with special polling
|
// Retry with special polling
|
||||||
const byte_t *pbtSensfReqNfcForum = (byte_t*)"\x00\x12\xfc\x01\x00";
|
const uint8_t *pbtSensfReqNfcForum = (uint8_t*)"\x00\x12\xfc\x01\x00";
|
||||||
if (!nfc_initiator_select_passive_target(pnd, nm, pbtSensfReqNfcForum, 5, &nt)) {
|
if (nfc_initiator_select_passive_target(pnd, nm, pbtSensfReqNfcForum, 5, &nt) < 0) {
|
||||||
nfc_perror (pnd, "nfc_initiator_select_passive_target");
|
nfc_perror (pnd, "nfc_initiator_select_passive_target");
|
||||||
error = EXIT_FAILURE;
|
error = EXIT_FAILURE;
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -244,13 +249,13 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
//print_nfc_felica_info(nt.nti.nfi, true);
|
//print_nfc_felica_info(nt.nti.nfi, true);
|
||||||
|
|
||||||
if (!nfc_configure (pnd, NDO_EASY_FRAMING, false) || !nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
if ((nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, false) < 0) || (nfc_device_set_property_bool (pnd, NP_INFINITE_SELECT, false) < 0)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_device_set_property_bool");
|
||||||
error = EXIT_FAILURE;
|
error = EXIT_FAILURE;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_t data[1024];
|
uint8_t data[1024];
|
||||||
size_t data_len = sizeof(data);
|
size_t data_len = sizeof(data);
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
@ -271,7 +276,7 @@ main(int argc, char *argv[])
|
||||||
fprintf (message_stream, "NDEF data lenght: %d bytes\n", ndef_data_len);
|
fprintf (message_stream, "NDEF data lenght: %d bytes\n", ndef_data_len);
|
||||||
|
|
||||||
uint16_t ndef_calculated_checksum = 0;
|
uint16_t ndef_calculated_checksum = 0;
|
||||||
for (size_t n=0; n<14; n++)
|
for (size_t n = 0; n < 14; n++)
|
||||||
ndef_calculated_checksum += data[n];
|
ndef_calculated_checksum += data[n];
|
||||||
|
|
||||||
const uint16_t ndef_checksum = (data[14] << 8) + data[15];
|
const uint16_t ndef_checksum = (data[14] << 8) + data[15];
|
||||||
|
@ -291,7 +296,7 @@ main(int argc, char *argv[])
|
||||||
const uint16_t block_count_to_check = (ndef_data_len / 16) + 1;
|
const uint16_t block_count_to_check = (ndef_data_len / 16) + 1;
|
||||||
|
|
||||||
data_len = 0;
|
data_len = 0;
|
||||||
for (uint16_t b=0; b<(block_count_to_check/block_max_per_check); b+=block_max_per_check) {
|
for (uint16_t b = 0; b < (block_count_to_check/block_max_per_check); b += block_max_per_check) {
|
||||||
size_t len = sizeof(data) - data_len;
|
size_t len = sizeof(data) - data_len;
|
||||||
if(!nfc_forum_tag_type3_check (pnd, nt, 1+b, MIN(block_max_per_check, (block_count_to_check-(b*block_max_per_check))), data + data_len, &len)) {
|
if(!nfc_forum_tag_type3_check (pnd, nt, 1+b, MIN(block_max_per_check, (block_count_to_check-(b*block_max_per_check))), data + data_len, &len)) {
|
||||||
nfc_perror (pnd, "nfc_forum_tag_type3_check");
|
nfc_perror (pnd, "nfc_forum_tag_type3_check");
|
||||||
|
@ -309,7 +314,8 @@ main(int argc, char *argv[])
|
||||||
error:
|
error:
|
||||||
fclose (ndef_stream);
|
fclose (ndef_stream);
|
||||||
if (pnd) {
|
if (pnd) {
|
||||||
nfc_disconnect (pnd);
|
nfc_close (pnd);
|
||||||
}
|
}
|
||||||
|
nfc_exit (NULL);
|
||||||
exit (error);
|
exit (error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,12 +57,12 @@
|
||||||
#define MAX_FRAME_LEN 264
|
#define MAX_FRAME_LEN 264
|
||||||
#define MAX_DEVICE_COUNT 2
|
#define MAX_DEVICE_COUNT 2
|
||||||
|
|
||||||
static byte_t abtCapdu[MAX_FRAME_LEN];
|
static uint8_t abtCapdu[MAX_FRAME_LEN];
|
||||||
static size_t szCapduLen;
|
static size_t szCapduLen;
|
||||||
static byte_t abtRapdu[MAX_FRAME_LEN];
|
static uint8_t abtRapdu[MAX_FRAME_LEN];
|
||||||
static size_t szRapduLen;
|
static size_t szRapduLen;
|
||||||
static nfc_device_t *pndInitiator;
|
static nfc_device *pndInitiator;
|
||||||
static nfc_device_t *pndTarget;
|
static nfc_device *pndTarget;
|
||||||
static bool quitting = false;
|
static bool quitting = false;
|
||||||
static bool quiet_output = false;
|
static bool quiet_output = false;
|
||||||
static bool initiator_only_mode = false;
|
static bool initiator_only_mode = false;
|
||||||
|
@ -92,29 +92,29 @@ print_usage (char *argv[])
|
||||||
printf ("\t-n N\tAdds a waiting time of N seconds (integer) in the relay to mimic long distance.\n");
|
printf ("\t-n N\tAdds a waiting time of N seconds (integer) in the relay to mimic long distance.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool print_hex_fd4 (const byte_t * pbtData, const size_t szBytes, const char * pchPrefix)
|
bool print_hex_fd4 (const uint8_t *pbtData, const size_t szBytes, const char *pchPrefix)
|
||||||
{
|
{
|
||||||
size_t szPos;
|
size_t szPos;
|
||||||
if (szBytes > MAX_FRAME_LEN) {
|
if (szBytes > MAX_FRAME_LEN) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if (fprintf (fd4, "#%s %04zx: ", pchPrefix, szBytes)<0) {
|
if (fprintf (fd4, "#%s %04zx: ", pchPrefix, szBytes) < 0) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (szPos = 0; szPos < szBytes; szPos++) {
|
for (szPos = 0; szPos < szBytes; szPos++) {
|
||||||
if (fprintf (fd4, "%02x ", pbtData[szPos])<0) {
|
if (fprintf (fd4, "%02x ", pbtData[szPos]) < 0) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fprintf (fd4, "\n")<0) {
|
if (fprintf (fd4, "\n") < 0) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
fflush(fd4);
|
fflush(fd4);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool scan_hex_fd3 (byte_t *pbtData, size_t *pszBytes, const char * pchPrefix)
|
bool scan_hex_fd3 (uint8_t *pbtData, size_t *pszBytes, const char *pchPrefix)
|
||||||
{
|
{
|
||||||
size_t szPos;
|
size_t szPos;
|
||||||
unsigned int uiBytes;
|
unsigned int uiBytes;
|
||||||
|
@ -129,7 +129,7 @@ bool scan_hex_fd3 (byte_t *pbtData, size_t *pszBytes, const char * pchPrefix)
|
||||||
}
|
}
|
||||||
strncpy(pchScan, pchPrefix, 250);
|
strncpy(pchScan, pchPrefix, 250);
|
||||||
strcat(pchScan, " %04x:");
|
strcat(pchScan, " %04x:");
|
||||||
if (fscanf (fd3, pchScan, &uiBytes)<1) {
|
if (fscanf (fd3, pchScan, &uiBytes) < 1) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
*pszBytes=uiBytes;
|
*pszBytes=uiBytes;
|
||||||
|
@ -137,7 +137,7 @@ bool scan_hex_fd3 (byte_t *pbtData, size_t *pszBytes, const char * pchPrefix)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
for (szPos = 0; szPos < *pszBytes; szPos++) {
|
for (szPos = 0; szPos < *pszBytes; szPos++) {
|
||||||
if (fscanf (fd3, "%02x", &uiData)<1) {
|
if (fscanf (fd3, "%02x", &uiData) < 1) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
pbtData[szPos]=uiData;
|
pbtData[szPos]=uiData;
|
||||||
|
@ -149,10 +149,8 @@ int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int arg;
|
int arg;
|
||||||
size_t szFound;
|
|
||||||
nfc_device_desc_t *pnddDevices;
|
|
||||||
const char *acLibnfcVersion = nfc_version ();
|
const char *acLibnfcVersion = nfc_version ();
|
||||||
nfc_target_t ntRealTarget;
|
nfc_target ntRealTarget;
|
||||||
|
|
||||||
// Get commandline options
|
// Get commandline options
|
||||||
for (arg = 1; arg < argc; arg++) {
|
for (arg = 1; arg < argc; arg++) {
|
||||||
|
@ -170,7 +168,7 @@ main (int argc, char *argv[])
|
||||||
initiator_only_mode = true;
|
initiator_only_mode = true;
|
||||||
target_only_mode = false;
|
target_only_mode = false;
|
||||||
} else if (0 == strcmp (argv[arg], "-n")) {
|
} else if (0 == strcmp (argv[arg], "-n")) {
|
||||||
if (++arg==argc || (sscanf(argv[arg], "%i", &waiting_time)<1)) {
|
if (++arg == argc || (sscanf(argv[arg], "%i", &waiting_time) < 1)) {
|
||||||
ERR ("Missing or wrong waiting time value: %s.", argv[arg]);
|
ERR ("Missing or wrong waiting time value: %s.", argv[arg]);
|
||||||
print_usage (argv);
|
print_usage (argv);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
@ -192,13 +190,11 @@ main (int argc, char *argv[])
|
||||||
signal (SIGINT, (void (*)()) intr_hdlr);
|
signal (SIGINT, (void (*)()) intr_hdlr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Allocate memory to put the result of available devices listing
|
nfc_init (NULL);
|
||||||
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
|
|
||||||
fprintf (stderr, "malloc() failed\n");
|
nfc_connstring connstrings[MAX_DEVICE_COUNT];
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
// List available devices
|
// List available devices
|
||||||
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound);
|
size_t szFound = nfc_list_devices (NULL, connstrings, MAX_DEVICE_COUNT);
|
||||||
|
|
||||||
if (initiator_only_mode || target_only_mode) {
|
if (initiator_only_mode || target_only_mode) {
|
||||||
if (szFound < 1) {
|
if (szFound < 1) {
|
||||||
|
@ -210,7 +206,7 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (szFound < 2) {
|
if (szFound < 2) {
|
||||||
ERR ("%zd device found but two connected devices are needed to relay NFC.", szFound);
|
ERR ("%zd device found but two opened devices are needed to relay NFC.", szFound);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,35 +215,37 @@ main (int argc, char *argv[])
|
||||||
// Try to open the NFC reader used as initiator
|
// Try to open the NFC reader used as initiator
|
||||||
// Little hack to allow using initiator no matter if
|
// Little hack to allow using initiator no matter if
|
||||||
// there is already a target used locally or not on the same machine:
|
// there is already a target used locally or not on the same machine:
|
||||||
// if there is more than one readers connected we connect to the second reader
|
// if there is more than one readers opened we open the second reader
|
||||||
// (we hope they're always detected in the same order)
|
// (we hope they're always detected in the same order)
|
||||||
if (szFound == 1) {
|
if (szFound == 1) {
|
||||||
pndInitiator = nfc_connect (&(pnddDevices[0]));
|
pndInitiator = nfc_open (NULL, connstrings[0]);
|
||||||
} else {
|
} else {
|
||||||
pndInitiator = nfc_connect (&(pnddDevices[1]));
|
pndInitiator = nfc_open (NULL, connstrings[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pndInitiator) {
|
if (!pndInitiator) {
|
||||||
printf ("Error connecting NFC reader\n");
|
printf ("Error opening NFC reader\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Connected to the NFC reader device: %s\n", pndInitiator->acName);
|
printf ("NFC reader device: %s opened\n", nfc_device_get_name (pndInitiator));
|
||||||
|
|
||||||
if (!nfc_initiator_init (pndInitiator)) {
|
if (nfc_initiator_init (pndInitiator) < 0) {
|
||||||
printf ("Error: fail initializing initiator\n");
|
printf ("Error: fail initializing initiator\n");
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to find a ISO 14443-4A tag
|
// Try to find a ISO 14443-4A tag
|
||||||
nfc_modulation_t nm = {
|
nfc_modulation nm = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
.nbr = NBR_106,
|
.nbr = NBR_106,
|
||||||
};
|
};
|
||||||
if (!nfc_initiator_select_passive_target (pndInitiator, nm, NULL, 0, &ntRealTarget)) {
|
if (nfc_initiator_select_passive_target (pndInitiator, nm, NULL, 0, &ntRealTarget) < 0) {
|
||||||
printf ("Error: no tag was found\n");
|
printf ("Error: no tag was found\n");
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,22 +254,26 @@ main (int argc, char *argv[])
|
||||||
if (initiator_only_mode) {
|
if (initiator_only_mode) {
|
||||||
if (print_hex_fd4(ntRealTarget.nti.nai.abtUid, ntRealTarget.nti.nai.szUidLen, "UID") != EXIT_SUCCESS) {
|
if (print_hex_fd4(ntRealTarget.nti.nai.abtUid, ntRealTarget.nti.nai.szUidLen, "UID") != EXIT_SUCCESS) {
|
||||||
fprintf (stderr, "Error while printing UID to FD4\n");
|
fprintf (stderr, "Error while printing UID to FD4\n");
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (print_hex_fd4(ntRealTarget.nti.nai.abtAtqa, 2, "ATQA") != EXIT_SUCCESS) {
|
if (print_hex_fd4(ntRealTarget.nti.nai.abtAtqa, 2, "ATQA") != EXIT_SUCCESS) {
|
||||||
fprintf (stderr, "Error while printing ATQA to FD4\n");
|
fprintf (stderr, "Error while printing ATQA to FD4\n");
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (print_hex_fd4(&(ntRealTarget.nti.nai.btSak), 1, "SAK") != EXIT_SUCCESS) {
|
if (print_hex_fd4(&(ntRealTarget.nti.nai.btSak), 1, "SAK") != EXIT_SUCCESS) {
|
||||||
fprintf (stderr, "Error while printing SAK to FD4\n");
|
fprintf (stderr, "Error while printing SAK to FD4\n");
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (print_hex_fd4(ntRealTarget.nti.nai.abtAts, ntRealTarget.nti.nai.szAtsLen, "ATS") != EXIT_SUCCESS) {
|
if (print_hex_fd4(ntRealTarget.nti.nai.abtAts, ntRealTarget.nti.nai.szAtsLen, "ATS") != EXIT_SUCCESS) {
|
||||||
fprintf (stderr, "Error while printing ATS to FD4\n");
|
fprintf (stderr, "Error while printing ATS to FD4\n");
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,7 +286,7 @@ main (int argc, char *argv[])
|
||||||
printf ("Hint: tag <---> initiator (relay) <---> target (relay) <---> original reader\n\n");
|
printf ("Hint: tag <---> initiator (relay) <---> target (relay) <---> original reader\n\n");
|
||||||
}
|
}
|
||||||
if (!initiator_only_mode) {
|
if (!initiator_only_mode) {
|
||||||
nfc_target_t ntEmulatedTarget = {
|
nfc_target ntEmulatedTarget = {
|
||||||
.nm = {
|
.nm = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
.nbr = NBR_106,
|
.nbr = NBR_106,
|
||||||
|
@ -294,22 +296,25 @@ main (int argc, char *argv[])
|
||||||
size_t foo;
|
size_t foo;
|
||||||
if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtUid, &(ntEmulatedTarget.nti.nai.szUidLen), "UID") != EXIT_SUCCESS) {
|
if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtUid, &(ntEmulatedTarget.nti.nai.szUidLen), "UID") != EXIT_SUCCESS) {
|
||||||
fprintf (stderr, "Error while scanning UID from FD3\n");
|
fprintf (stderr, "Error while scanning UID from FD3\n");
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAtqa, &foo, "ATQA") != EXIT_SUCCESS) {
|
if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAtqa, &foo, "ATQA") != EXIT_SUCCESS) {
|
||||||
fprintf (stderr, "Error while scanning ATQA from FD3\n");
|
fprintf (stderr, "Error while scanning ATQA from FD3\n");
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (scan_hex_fd3(&(ntEmulatedTarget.nti.nai.btSak), &foo, "SAK") != EXIT_SUCCESS) {
|
if (scan_hex_fd3(&(ntEmulatedTarget.nti.nai.btSak), &foo, "SAK") != EXIT_SUCCESS) {
|
||||||
fprintf (stderr, "Error while scanning SAK from FD3\n");
|
fprintf (stderr, "Error while scanning SAK from FD3\n");
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAts, &(ntEmulatedTarget.nti.nai.szAtsLen), "ATS") != EXIT_SUCCESS) {
|
if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAts, &(ntEmulatedTarget.nti.nai.szAtsLen), "ATS") != EXIT_SUCCESS) {
|
||||||
fprintf (stderr, "Error while scanning ATS from FD3\n");
|
fprintf (stderr, "Error while scanning ATS from FD3\n");
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -331,11 +336,11 @@ main (int argc, char *argv[])
|
||||||
// PC/SC pseudo-ATR = 3B 80 80 01 01 if there is no historical bytes
|
// PC/SC pseudo-ATR = 3B 80 80 01 01 if there is no historical bytes
|
||||||
|
|
||||||
// Creates ATS and copy max 48 bytes of Tk:
|
// Creates ATS and copy max 48 bytes of Tk:
|
||||||
byte_t * pbtTk;
|
uint8_t * pbtTk;
|
||||||
size_t szTk;
|
size_t szTk;
|
||||||
pbtTk = iso14443a_locate_historical_bytes (ntEmulatedTarget.nti.nai.abtAts, ntEmulatedTarget.nti.nai.szAtsLen, &szTk);
|
pbtTk = iso14443a_locate_historical_bytes (ntEmulatedTarget.nti.nai.abtAts, ntEmulatedTarget.nti.nai.szAtsLen, &szTk);
|
||||||
szTk = (szTk > 48) ? 48 : szTk;
|
szTk = (szTk > 48) ? 48 : szTk;
|
||||||
byte_t pbtTkt[48];
|
uint8_t pbtTkt[48];
|
||||||
memcpy(pbtTkt, pbtTk, szTk);
|
memcpy(pbtTkt, pbtTk, szTk);
|
||||||
ntEmulatedTarget.nti.nai.abtAts[0] = 0x75;
|
ntEmulatedTarget.nti.nai.abtAts[0] = 0x75;
|
||||||
ntEmulatedTarget.nti.nai.abtAts[1] = 0x33;
|
ntEmulatedTarget.nti.nai.abtAts[1] = 0x33;
|
||||||
|
@ -348,23 +353,26 @@ main (int argc, char *argv[])
|
||||||
print_nfc_iso14443a_info (ntEmulatedTarget.nti.nai, false);
|
print_nfc_iso14443a_info (ntEmulatedTarget.nti.nai, false);
|
||||||
|
|
||||||
// Try to open the NFC emulator device
|
// Try to open the NFC emulator device
|
||||||
pndTarget = nfc_connect (&(pnddDevices[0]));
|
pndTarget = nfc_open (NULL, connstrings[0]);
|
||||||
if (pndTarget == NULL) {
|
if (pndTarget == NULL) {
|
||||||
printf ("Error connecting NFC emulator device\n");
|
printf ("Error opening NFC emulator device\n");
|
||||||
if (!target_only_mode) {
|
if (!target_only_mode) {
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
}
|
}
|
||||||
|
nfc_exit (NULL);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Connected to the NFC emulator device: %s\n", pndTarget->acName);
|
printf ("NFC emulator device: %s opened\n", nfc_device_get_name (pndTarget));
|
||||||
|
|
||||||
if (!nfc_target_init (pndTarget, &ntEmulatedTarget, abtCapdu, &szCapduLen)) {
|
szCapduLen = sizeof (abtCapdu);
|
||||||
|
if (nfc_target_init (pndTarget, &ntEmulatedTarget, abtCapdu, szCapduLen, 0) < 0) {
|
||||||
ERR ("%s", "Initialization of NFC emulator failed");
|
ERR ("%s", "Initialization of NFC emulator failed");
|
||||||
if (!target_only_mode) {
|
if (!target_only_mode) {
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
}
|
}
|
||||||
nfc_disconnect (pndTarget);
|
nfc_close (pndTarget);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
printf ("%s\n", "Done, relaying frames now!");
|
printf ("%s\n", "Done, relaying frames now!");
|
||||||
|
@ -373,27 +381,32 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
while (!quitting) {
|
while (!quitting) {
|
||||||
bool ret;
|
bool ret;
|
||||||
|
int res = 0;
|
||||||
if (!initiator_only_mode) {
|
if (!initiator_only_mode) {
|
||||||
// Receive external reader command through target
|
// Receive external reader command through target
|
||||||
if (!nfc_target_receive_bytes(pndTarget,abtCapdu,&szCapduLen, NULL)) {
|
if ((res = nfc_target_receive_bytes(pndTarget, abtCapdu, sizeof (abtCapdu), 0)) < 0) {
|
||||||
nfc_perror (pndTarget, "nfc_target_receive_bytes");
|
nfc_perror (pndTarget, "nfc_target_receive_bytes");
|
||||||
if (!target_only_mode) {
|
if (!target_only_mode) {
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
}
|
}
|
||||||
nfc_disconnect (pndTarget);
|
nfc_close (pndTarget);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
szCapduLen = (size_t) res;
|
||||||
if (target_only_mode) {
|
if (target_only_mode) {
|
||||||
if (print_hex_fd4(abtCapdu, szCapduLen, "C-APDU") != EXIT_SUCCESS) {
|
if (print_hex_fd4(abtCapdu, szCapduLen, "C-APDU") != EXIT_SUCCESS) {
|
||||||
fprintf (stderr, "Error while printing C-APDU to FD4\n");
|
fprintf (stderr, "Error while printing C-APDU to FD4\n");
|
||||||
nfc_disconnect (pndTarget);
|
nfc_close (pndTarget);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (scan_hex_fd3(abtCapdu, &szCapduLen, "C-APDU") != EXIT_SUCCESS) {
|
if (scan_hex_fd3(abtCapdu, &szCapduLen, "C-APDU") != EXIT_SUCCESS) {
|
||||||
fprintf (stderr, "Error while scanning C-APDU from FD3\n");
|
fprintf (stderr, "Error while scanning C-APDU from FD3\n");
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -405,12 +418,13 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
if (!target_only_mode) {
|
if (!target_only_mode) {
|
||||||
// Forward the frame to the original tag
|
// Forward the frame to the original tag
|
||||||
ret = nfc_initiator_transceive_bytes
|
ret = (nfc_initiator_transceive_bytes
|
||||||
(pndInitiator, abtCapdu, szCapduLen, abtRapdu, &szRapduLen, NULL);
|
(pndInitiator, abtCapdu, szCapduLen, abtRapdu, &szRapduLen, 0) < 0) ? 0 : 1;
|
||||||
} else {
|
} else {
|
||||||
if (scan_hex_fd3(abtRapdu, &szRapduLen, "R-APDU") != EXIT_SUCCESS) {
|
if (scan_hex_fd3(abtRapdu, &szRapduLen, "R-APDU") != EXIT_SUCCESS) {
|
||||||
fprintf (stderr, "Error while scanning R-APDU from FD3\n");
|
fprintf (stderr, "Error while scanning R-APDU from FD3\n");
|
||||||
nfc_disconnect (pndTarget);
|
nfc_close (pndTarget);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
ret = true;
|
ret = true;
|
||||||
|
@ -430,20 +444,23 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
if (!initiator_only_mode) {
|
if (!initiator_only_mode) {
|
||||||
// Transmit the response bytes
|
// Transmit the response bytes
|
||||||
if (!nfc_target_send_bytes(pndTarget, abtRapdu, szRapduLen, NULL)) {
|
if (nfc_target_send_bytes(pndTarget, abtRapdu, szRapduLen, 0) < 0) {
|
||||||
nfc_perror (pndTarget, "nfc_target_send_bytes");
|
nfc_perror (pndTarget, "nfc_target_send_bytes");
|
||||||
if (!target_only_mode) {
|
if (!target_only_mode) {
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
}
|
}
|
||||||
if (!initiator_only_mode) {
|
if (!initiator_only_mode) {
|
||||||
nfc_disconnect (pndTarget);
|
nfc_close (pndTarget);
|
||||||
|
nfc_exit (NULL);
|
||||||
}
|
}
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (print_hex_fd4(abtRapdu, szRapduLen, "R-APDU") != EXIT_SUCCESS) {
|
if (print_hex_fd4(abtRapdu, szRapduLen, "R-APDU") != EXIT_SUCCESS) {
|
||||||
fprintf (stderr, "Error while printing R-APDU to FD4\n");
|
fprintf (stderr, "Error while printing R-APDU to FD4\n");
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
|
nfc_exit (NULL);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,11 +468,12 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target_only_mode) {
|
if (!target_only_mode) {
|
||||||
nfc_disconnect (pndInitiator);
|
nfc_close (pndInitiator);
|
||||||
}
|
}
|
||||||
if (!initiator_only_mode) {
|
if (!initiator_only_mode) {
|
||||||
nfc_disconnect (pndTarget);
|
nfc_close (pndTarget);
|
||||||
}
|
}
|
||||||
|
nfc_exit (NULL);
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
#include "nfc-utils.h"
|
#include "nfc-utils.h"
|
||||||
|
|
||||||
static const byte_t OddParity[256] = {
|
static const uint8_t OddParity[256] = {
|
||||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
@ -52,14 +52,14 @@ static const byte_t OddParity[256] = {
|
||||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
|
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
|
||||||
};
|
};
|
||||||
|
|
||||||
byte_t
|
uint8_t
|
||||||
oddparity (const byte_t bt)
|
oddparity (const uint8_t bt)
|
||||||
{
|
{
|
||||||
return OddParity[bt];
|
return OddParity[bt];
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
oddparity_bytes_ts (const byte_t * pbtData, const size_t szLen, byte_t * pbtPar)
|
oddparity_bytes_ts (const uint8_t *pbtData, const size_t szLen, uint8_t *pbtPar)
|
||||||
{
|
{
|
||||||
size_t szByteNr;
|
size_t szByteNr;
|
||||||
// Calculate the parity bits for the command
|
// Calculate the parity bits for the command
|
||||||
|
@ -69,7 +69,7 @@ oddparity_bytes_ts (const byte_t * pbtData, const size_t szLen, byte_t * pbtPar)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_hex (const byte_t * pbtData, const size_t szBytes)
|
print_hex (const uint8_t *pbtData, const size_t szBytes)
|
||||||
{
|
{
|
||||||
size_t szPos;
|
size_t szPos;
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ print_hex (const byte_t * pbtData, const size_t szBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_hex_bits (const byte_t * pbtData, const size_t szBits)
|
print_hex_bits (const uint8_t *pbtData, const size_t szBits)
|
||||||
{
|
{
|
||||||
uint8_t uRemainder;
|
uint8_t uRemainder;
|
||||||
size_t szPos;
|
size_t szPos;
|
||||||
|
@ -102,7 +102,7 @@ print_hex_bits (const byte_t * pbtData, const size_t szBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_hex_par (const byte_t * pbtData, const size_t szBits, const byte_t * pbtDataPar)
|
print_hex_par (const uint8_t *pbtData, const size_t szBits, const uint8_t *pbtDataPar)
|
||||||
{
|
{
|
||||||
uint8_t uRemainder;
|
uint8_t uRemainder;
|
||||||
size_t szPos;
|
size_t szPos;
|
||||||
|
@ -133,7 +133,7 @@ print_hex_par (const byte_t * pbtData, const size_t szBits, const byte_t * pbtDa
|
||||||
#define SAK_ISO18092_COMPLIANT 0x40
|
#define SAK_ISO18092_COMPLIANT 0x40
|
||||||
|
|
||||||
void
|
void
|
||||||
print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose)
|
print_nfc_iso14443a_info (const nfc_iso14443a_info nai, bool verbose)
|
||||||
{
|
{
|
||||||
printf (" ATQA (SENS_RES): ");
|
printf (" ATQA (SENS_RES): ");
|
||||||
print_hex (nai.abtAtqa, 2);
|
print_hex (nai.abtAtqa, 2);
|
||||||
|
@ -202,7 +202,7 @@ print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose)
|
||||||
|
|
||||||
size_t offset = 1;
|
size_t offset = 1;
|
||||||
if (nai.abtAts[0] & 0x10) { // TA(1) present
|
if (nai.abtAts[0] & 0x10) { // TA(1) present
|
||||||
byte_t TA = nai.abtAts[offset];
|
uint8_t TA = nai.abtAts[offset];
|
||||||
offset++;
|
offset++;
|
||||||
printf ("* Bit Rate Capability:\n");
|
printf ("* Bit Rate Capability:\n");
|
||||||
if (TA == 0) {
|
if (TA == 0) {
|
||||||
|
@ -234,7 +234,7 @@ print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nai.abtAts[0] & 0x20) { // TB(1) present
|
if (nai.abtAts[0] & 0x20) { // TB(1) present
|
||||||
byte_t TB= nai.abtAts[offset];
|
uint8_t TB= nai.abtAts[offset];
|
||||||
offset++;
|
offset++;
|
||||||
printf ("* Frame Waiting Time: %.4g ms\n",256.0*16.0*(1<<((TB & 0xf0) >> 4))/13560.0);
|
printf ("* Frame Waiting Time: %.4g ms\n",256.0*16.0*(1<<((TB & 0xf0) >> 4))/13560.0);
|
||||||
if ((TB & 0x0f) == 0) {
|
if ((TB & 0x0f) == 0) {
|
||||||
|
@ -244,7 +244,7 @@ print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nai.abtAts[0] & 0x40) { // TC(1) present
|
if (nai.abtAts[0] & 0x40) { // TC(1) present
|
||||||
byte_t TC = nai.abtAts[offset];
|
uint8_t TC = nai.abtAts[offset];
|
||||||
offset++;
|
offset++;
|
||||||
if (TC & 0x1) {
|
if (TC & 0x1) {
|
||||||
printf("* Node ADdress supported\n");
|
printf("* Node ADdress supported\n");
|
||||||
|
@ -260,20 +260,20 @@ print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose)
|
||||||
if (nai.szAtsLen > offset) {
|
if (nai.szAtsLen > offset) {
|
||||||
printf ("* Historical bytes Tk: " );
|
printf ("* Historical bytes Tk: " );
|
||||||
print_hex (nai.abtAts + offset, (nai.szAtsLen - offset));
|
print_hex (nai.abtAts + offset, (nai.szAtsLen - offset));
|
||||||
byte_t CIB = nai.abtAts[offset];
|
uint8_t CIB = nai.abtAts[offset];
|
||||||
offset++;
|
offset++;
|
||||||
if (CIB != 0x00 && CIB != 0x10 && (CIB & 0xf0) != 0x80) {
|
if (CIB != 0x00 && CIB != 0x10 && (CIB & 0xf0) != 0x80) {
|
||||||
printf(" * Proprietary format\n");
|
printf(" * Proprietary format\n");
|
||||||
if (CIB == 0xc1) {
|
if (CIB == 0xc1) {
|
||||||
printf(" * Tag byte: Mifare or virtual cards of various types\n");
|
printf(" * Tag byte: Mifare or virtual cards of various types\n");
|
||||||
byte_t L = nai.abtAts[offset];
|
uint8_t L = nai.abtAts[offset];
|
||||||
offset++;
|
offset++;
|
||||||
if (L != (nai.szAtsLen - offset)) {
|
if (L != (nai.szAtsLen - offset)) {
|
||||||
printf(" * Warning: Type Identification Coding length (%i)", L);
|
printf(" * Warning: Type Identification Coding length (%i)", L);
|
||||||
printf(" not matching Tk length (%zi)\n", (nai.szAtsLen - offset));
|
printf(" not matching Tk length (%zi)\n", (nai.szAtsLen - offset));
|
||||||
}
|
}
|
||||||
if ((nai.szAtsLen - offset - 2) > 0) { // Omit 2 CRC bytes
|
if ((nai.szAtsLen - offset - 2) > 0) { // Omit 2 CRC bytes
|
||||||
byte_t CTC = nai.abtAts[offset];
|
uint8_t CTC = nai.abtAts[offset];
|
||||||
offset++;
|
offset++;
|
||||||
printf(" * Chip Type: ");
|
printf(" * Chip Type: ");
|
||||||
switch (CTC & 0xf0) {
|
switch (CTC & 0xf0) {
|
||||||
|
@ -316,7 +316,7 @@ print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((nai.szAtsLen - offset) > 0) { // Omit 2 CRC bytes
|
if ((nai.szAtsLen - offset) > 0) { // Omit 2 CRC bytes
|
||||||
byte_t CVC = nai.abtAts[offset];
|
uint8_t CVC = nai.abtAts[offset];
|
||||||
offset++;
|
offset++;
|
||||||
printf(" * Chip Status: ");
|
printf(" * Chip Status: ");
|
||||||
switch (CVC & 0xf0) {
|
switch (CVC & 0xf0) {
|
||||||
|
@ -350,7 +350,7 @@ print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((nai.szAtsLen - offset) > 0) { // Omit 2 CRC bytes
|
if ((nai.szAtsLen - offset) > 0) { // Omit 2 CRC bytes
|
||||||
byte_t VCS = nai.abtAts[offset];
|
uint8_t VCS = nai.abtAts[offset];
|
||||||
offset++;
|
offset++;
|
||||||
printf(" * Specifics (Virtual Card Selection):\n");
|
printf(" * Specifics (Virtual Card Selection):\n");
|
||||||
if ((VCS & 0x09) == 0x00) {
|
if ((VCS & 0x09) == 0x00) {
|
||||||
|
@ -530,7 +530,7 @@ print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_nfc_felica_info (const nfc_felica_info_t nfi, bool verbose)
|
print_nfc_felica_info (const nfc_felica_info nfi, bool verbose)
|
||||||
{
|
{
|
||||||
(void) verbose;
|
(void) verbose;
|
||||||
printf (" ID (NFCID2): ");
|
printf (" ID (NFCID2): ");
|
||||||
|
@ -542,7 +542,7 @@ print_nfc_felica_info (const nfc_felica_info_t nfi, bool verbose)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_nfc_jewel_info (const nfc_jewel_info_t nji, bool verbose)
|
print_nfc_jewel_info (const nfc_jewel_info nji, bool verbose)
|
||||||
{
|
{
|
||||||
(void) verbose;
|
(void) verbose;
|
||||||
printf (" ATQA (SENS_RES): ");
|
printf (" ATQA (SENS_RES): ");
|
||||||
|
@ -555,7 +555,7 @@ print_nfc_jewel_info (const nfc_jewel_info_t nji, bool verbose)
|
||||||
#define PI_NAD_SUPPORTED 0x01
|
#define PI_NAD_SUPPORTED 0x01
|
||||||
#define PI_CID_SUPPORTED 0x02
|
#define PI_CID_SUPPORTED 0x02
|
||||||
void
|
void
|
||||||
print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi, bool verbose)
|
print_nfc_iso14443b_info (const nfc_iso14443b_info nbi, bool verbose)
|
||||||
{
|
{
|
||||||
const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
|
const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
|
||||||
printf (" PUPI: ");
|
printf (" PUPI: ");
|
||||||
|
@ -610,7 +610,7 @@ print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi, bool verbose)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_nfc_iso14443bi_info (const nfc_iso14443bi_info_t nii, bool verbose)
|
print_nfc_iso14443bi_info (const nfc_iso14443bi_info nii, bool verbose)
|
||||||
{
|
{
|
||||||
printf (" DIV: ");
|
printf (" DIV: ");
|
||||||
print_hex (nii.abtDIV, 4);
|
print_hex (nii.abtDIV, 4);
|
||||||
|
@ -634,7 +634,7 @@ print_nfc_iso14443bi_info (const nfc_iso14443bi_info_t nii, bool verbose)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_nfc_iso14443b2sr_info (const nfc_iso14443b2sr_info_t nsi, bool verbose)
|
print_nfc_iso14443b2sr_info (const nfc_iso14443b2sr_info nsi, bool verbose)
|
||||||
{
|
{
|
||||||
(void) verbose;
|
(void) verbose;
|
||||||
printf (" UID: ");
|
printf (" UID: ");
|
||||||
|
@ -642,7 +642,7 @@ print_nfc_iso14443b2sr_info (const nfc_iso14443b2sr_info_t nsi, bool verbose)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_nfc_iso14443b2ct_info (const nfc_iso14443b2ct_info_t nci, bool verbose)
|
print_nfc_iso14443b2ct_info (const nfc_iso14443b2ct_info nci, bool verbose)
|
||||||
{
|
{
|
||||||
(void) verbose;
|
(void) verbose;
|
||||||
uint32_t uid;
|
uint32_t uid;
|
||||||
|
@ -655,7 +655,7 @@ print_nfc_iso14443b2ct_info (const nfc_iso14443b2ct_info_t nci, bool verbose)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose)
|
print_nfc_dep_info (const nfc_dep_info ndi, bool verbose)
|
||||||
{
|
{
|
||||||
(void) verbose;
|
(void) verbose;
|
||||||
printf (" NFCID3: ");
|
printf (" NFCID3: ");
|
||||||
|
@ -670,53 +670,8 @@ print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Tries to parse arguments to find device descriptions.
|
|
||||||
* @return Returns the list of found device descriptions.
|
|
||||||
*/
|
|
||||||
nfc_device_desc_t *
|
|
||||||
parse_args (int argc, const char *argv[], size_t * szFound, bool * verbose)
|
|
||||||
{
|
|
||||||
nfc_device_desc_t *pndd = 0;
|
|
||||||
int arg;
|
|
||||||
*szFound = 0;
|
|
||||||
|
|
||||||
// Get commandline options
|
|
||||||
for (arg = 1; arg < argc; arg++) {
|
|
||||||
|
|
||||||
if (0 == strcmp (argv[arg], "--device")) {
|
|
||||||
// FIXME: this device selection by command line options is terrible & does not support USB/PCSC drivers
|
|
||||||
if (argc > arg + 1) {
|
|
||||||
char buffer[256];
|
|
||||||
|
|
||||||
pndd = malloc (sizeof (nfc_device_desc_t));
|
|
||||||
|
|
||||||
strncpy (buffer, argv[++arg], 256);
|
|
||||||
|
|
||||||
// Driver.
|
|
||||||
pndd->pcDriver = (char *) malloc (256);
|
|
||||||
strcpy (pndd->pcDriver, strtok (buffer, ":"));
|
|
||||||
|
|
||||||
// Port.
|
|
||||||
strcpy (pndd->acPort, strtok (NULL, ":"));
|
|
||||||
|
|
||||||
// Speed.
|
|
||||||
sscanf (strtok (NULL, ":"), "%u", &pndd->uiSpeed);
|
|
||||||
|
|
||||||
*szFound = 1;
|
|
||||||
} else {
|
|
||||||
errx (1, "usage: %s [--device driver:port:speed]", argv[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((0 == strcmp (argv[arg], "-v")) || (0 == strcmp (argv[arg], "--verbose"))) {
|
|
||||||
*verbose = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pndd;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
str_nfc_baud_rate (const nfc_baud_rate_t nbr)
|
str_nfc_baud_rate (const nfc_baud_rate nbr)
|
||||||
{
|
{
|
||||||
switch(nbr) {
|
switch(nbr) {
|
||||||
case NBR_UNDEFINED:
|
case NBR_UNDEFINED:
|
||||||
|
@ -739,7 +694,7 @@ str_nfc_baud_rate (const nfc_baud_rate_t nbr)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_nfc_target (const nfc_target_t nt, bool verbose)
|
print_nfc_target (const nfc_target nt, bool verbose)
|
||||||
{
|
{
|
||||||
switch(nt.nm.nmt) {
|
switch(nt.nm.nmt) {
|
||||||
case NMT_ISO14443A:
|
case NMT_ISO14443A:
|
||||||
|
@ -771,7 +726,7 @@ print_nfc_target (const nfc_target_t nt, bool verbose)
|
||||||
print_nfc_iso14443b2ct_info (nt.nti.nci, verbose);
|
print_nfc_iso14443b2ct_info (nt.nti.nci, verbose);
|
||||||
break;
|
break;
|
||||||
case NMT_DEP:
|
case NMT_DEP:
|
||||||
printf ("D.E.P. (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
|
printf ("D.E.P. (%s, %s) target:\n", str_nfc_baud_rate(nt.nm.nbr), (nt.nti.ndi.ndm == NDM_ACTIVE)? "active mode" : "passive mode");
|
||||||
print_nfc_dep_info (nt.nti.ndi, verbose);
|
print_nfc_dep_info (nt.nti.ndi, verbose);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,24 +79,23 @@
|
||||||
# define ERR(...) warnx ("ERROR: " __VA_ARGS__ )
|
# define ERR(...) warnx ("ERROR: " __VA_ARGS__ )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
byte_t oddparity (const byte_t bt);
|
uint8_t oddparity (const uint8_t bt);
|
||||||
void oddparity_byte_ts (const byte_t * pbtData, const size_t szLen, byte_t * pbtPar);
|
void oddparity_uint8_ts (const uint8_t *pbtData, const size_t szLen, uint8_t *pbtPar);
|
||||||
|
|
||||||
void print_hex (const byte_t * pbtData, const size_t szLen);
|
void print_hex (const uint8_t *pbtData, const size_t szLen);
|
||||||
void print_hex_bits (const byte_t * pbtData, const size_t szBits);
|
void print_hex_bits (const uint8_t *pbtData, const size_t szBits);
|
||||||
void print_hex_par (const byte_t * pbtData, const size_t szBits, const byte_t * pbtDataPar);
|
void print_hex_par (const uint8_t *pbtData, const size_t szBits, const uint8_t *pbtDataPar);
|
||||||
|
|
||||||
void print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose);
|
void print_nfc_iso14443a_info (const nfc_iso14443a_info nai, bool verbose);
|
||||||
void print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi, bool verbose);
|
void print_nfc_iso14443b_info (const nfc_iso14443b_info nbi, bool verbose);
|
||||||
void print_nfc_iso14443bi_info (const nfc_iso14443bi_info_t nii, bool verbose);
|
void print_nfc_iso14443bi_info (const nfc_iso14443bi_info nii, bool verbose);
|
||||||
void print_nfc_iso14443b2sr_info (const nfc_iso14443b2sr_info_t nsi, bool verbose);
|
void print_nfc_iso14443b2sr_info (const nfc_iso14443b2sr_info nsi, bool verbose);
|
||||||
void print_nfc_iso14443b2ct_info (const nfc_iso14443b2ct_info_t nci, bool verbose);
|
void print_nfc_iso14443b2ct_info (const nfc_iso14443b2ct_info nci, bool verbose);
|
||||||
void print_nfc_felica_info (const nfc_felica_info_t nfi, bool verbose);
|
void print_nfc_felica_info (const nfc_felica_info nfi, bool verbose);
|
||||||
void print_nfc_jewel_info (const nfc_jewel_info_t nji, bool verbose);
|
void print_nfc_jewel_info (const nfc_jewel_info nji, bool verbose);
|
||||||
void print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose);
|
void print_nfc_dep_info (const nfc_dep_info ndi, bool verbose);
|
||||||
|
const char * str_nfc_baud_rate (const nfc_baud_rate nbr);
|
||||||
|
|
||||||
void print_nfc_target (const nfc_target_t nt, bool verbose);
|
void print_nfc_target (const nfc_target nt, bool verbose);
|
||||||
|
|
||||||
nfc_device_desc_t *parse_args (int argc, const char *argv[], size_t * szFound, bool * verbose);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue