Merge libnfc-1.5-new-api branch to trunk (r1168:1303).

This commit is contained in:
Audrey Diacre 2012-01-25 09:56:05 +00:00
commit 26245add73
82 changed files with 4481 additions and 3212 deletions

View file

@ -10,9 +10,7 @@ pkgconfig_DATA = libnfc.pc
EXTRA_DIST = \
CMakeLists.txt \
Doxyfile \
README-Windows.txt \
pn53x.conf \
pn53x.rules
README-Windows.txt
CLEANFILES = Doxygen.log coverage.info libnfc.pc

View file

@ -70,17 +70,6 @@ AC_TYPE_SIGNAL
LIBNFC_CFLAGS='-I$(top_srcdir)/libnfc -I$(top_builddir)/include -I$(top_srcdir)/include'
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)
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/modules/Makefile
contrib/Makefile
contrib/devd/Makefile
contrib/udev/Makefile
contrib/win32/Makefile
contrib/win32/sys/Makefile
examples/Makefile

View file

@ -1,4 +1,7 @@
SUBDIRS = win32
SUBDIRS = \
devd \
udev \
win32
EXTRA_DIST = \
windows.h

2
contrib/devd/Makefile.am Normal file
View file

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

2
contrib/udev/Makefile.am Normal file
View file

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

6
debian/changelog vendored
View file

@ -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
* Move nfc-emulate-nfcforum-tag2, nfc-emulate-nfcforum-tag4 and

View file

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

View file

@ -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)

View file

@ -4,6 +4,7 @@ bin_PROGRAMS = \
nfc-anticol \
nfc-dep-initiator \
nfc-dep-target \
nfc-emulate-forum-tag2 \
nfc-emulate-tag \
nfc-emulate-uid \
nfc-poll \
@ -16,6 +17,9 @@ bin_PROGRAMS += \
pn53x-tamashell
endif
check_PROGRAMS = \
quick_start_example1
# set the include path found by configure
INCLUDES = $(all_includes) $(LIBNFC_CFLAGS)
@ -33,6 +37,10 @@ nfc_relay_SOURCES = nfc-relay.c
nfc_relay_LDADD = $(top_builddir)/libnfc/libnfc.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_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la
@ -62,6 +70,11 @@ pn53x_tamashell_LDADD = $(top_builddir)/libnfc/libnfc.la \
$(top_builddir)/utils/libnfcutils.la
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 = \
nfc-anticol.1 \
nfc-dep-initiator.1 \
@ -74,9 +87,4 @@ dist_man_MANS = \
pn53x-sam.1 \
pn53x-tamashell.1
if HAS_LOG4C
AM_CFLAGS += @log4c_CFLAGS@
LIBADD = @log4c_LIBS@
endif
EXTRA_DIST = CMakeLists.txt

View file

@ -5,45 +5,42 @@
#include <stdlib.h>
#include <nfc/nfc.h>
void
print_hex (const byte_t * pbtData, const size_t szBytes)
{
size_t szPos;
for (szPos = 0; szPos < szBytes; szPos++) {
printf ("%02x ", pbtData[szPos]);
}
printf ("\n");
}
#include "utils/nfc-utils.h"
#include "libnfc/chips/pn53x.h"
int
main (int argc, const char *argv[])
{
nfc_device_t *pnd;
nfc_target_t nt;
nfc_device *pnd;
nfc_target nt;
nfc_init (NULL);
// Display libnfc version
const char *acLibnfcVersion = nfc_version ();
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
// Connect using the first available NFC device
pnd = nfc_connect (NULL);
// Open, using the first available NFC device
pnd = nfc_open (NULL, NULL);
if (pnd == NULL) {
fprintf (stderr, "Unable to connect to NFC device.");
ERR ("%s", "Unable to open NFC device.");
return EXIT_FAILURE;
}
// Set connected NFC device to initiator mode
nfc_initiator_init (pnd);
// Set opened NFC device to initiator mode
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
const nfc_modulation_t nmMifare = {
const nfc_modulation nmMifare = {
.nmt = NMT_ISO14443A,
.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 (" ATQA (SENS_RES): ");
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);
}
}
// Disconnect from NFC device
nfc_disconnect (pnd);
// Close NFC device
nfc_close (pnd);
nfc_exit (NULL);
return EXIT_SUCCESS;
}

View file

@ -51,31 +51,31 @@
#define MAX_FRAME_LEN 264
static byte_t abtRx[MAX_FRAME_LEN];
static size_t szRxBits;
static uint8_t abtRx[MAX_FRAME_LEN];
static int szRxBits;
static size_t szRx = sizeof(abtRx);
static byte_t abtRawUid[12];
static byte_t abtAtqa[2];
static byte_t abtSak;
static byte_t abtAts[MAX_FRAME_LEN];
static byte_t szAts = 0;
static uint8_t abtRawUid[12];
static uint8_t abtAtqa[2];
static uint8_t abtSak;
static uint8_t abtAts[MAX_FRAME_LEN];
static uint8_t szAts = 0;
static size_t szCL = 1;//Always start with Cascade Level 1 (CL1)
static nfc_device_t *pnd;
static nfc_device *pnd;
bool quiet_output = false;
bool force_rats = false;
bool iso_ats_supported = false;
// ISO14443A Anti-Collision Commands
byte_t abtReqa[1] = { 0x26 };
byte_t abtSelectAll[2] = { 0x93, 0x20 };
byte_t abtSelectTag[9] = { 0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
byte_t abtRats[4] = { 0xe0, 0x50, 0x00, 0x00 };
byte_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
uint8_t abtReqa[1] = { 0x26 };
uint8_t abtSelectAll[2] = { 0x93, 0x20 };
uint8_t abtSelectTag[9] = { 0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t abtRats[4] = { 0xe0, 0x50, 0x00, 0x00 };
uint8_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
#define CASCADE_BIT 0x04
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
if (!quiet_output) {
@ -83,7 +83,7 @@ transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
print_hex_bits (pbtTx, szTxBits);
}
// 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;
// Show received answer
@ -97,7 +97,7 @@ transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
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
if (!quiet_output) {
@ -105,7 +105,7 @@ transmit_bytes (const byte_t * pbtTx, const size_t szTx)
print_hex (pbtTx, szTx);
}
// 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;
// Show received answer
@ -148,39 +148,45 @@ main (int argc, char *argv[])
}
}
nfc_init (NULL);
// Try to open the NFC reader
pnd = nfc_connect (NULL);
pnd = nfc_open (NULL, NULL);
if (!pnd) {
printf ("Error connecting NFC reader\n");
printf ("Error opening NFC reader\n");
exit(EXIT_FAILURE);
}
// 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
if (!nfc_configure (pnd, NDO_HANDLE_CRC, false)) {
nfc_perror (pnd, "nfc_configure");
if (nfc_device_set_property_bool (pnd, NP_HANDLE_CRC, false) < 0) {
nfc_perror (pnd, "nfc_device_set_property_bool");
exit (EXIT_FAILURE);
}
// Use raw send/receive methods
if (!nfc_configure (pnd, NDO_EASY_FRAMING, false)) {
nfc_perror (pnd, "nfc_configure");
if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, false) < 0) {
nfc_perror (pnd, "nfc_device_set_property_bool");
exit (EXIT_FAILURE);
}
// Disable 14443-4 autoswitching
if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, false)) {
nfc_perror (pnd, "nfc_configure");
if (nfc_device_set_property_bool (pnd, NP_AUTO_ISO14443_4, false) < 0) {
nfc_perror (pnd, "nfc_device_set_property_bool");
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)
if (!transmit_bits (abtReqa, 7)) {
printf ("Error: No tag available\n");
nfc_disconnect (pnd);
nfc_close (pnd);
nfc_exit (NULL);
return 1;
}
memcpy (abtAtqa, abtRx, 2);
@ -309,6 +315,7 @@ main (int argc, char *argv[])
print_hex (abtAts, szAts);
}
nfc_disconnect (pnd);
nfc_close (pnd);
nfc_exit (NULL);
return 0;
}

View file

@ -48,7 +48,7 @@
#define MAX_FRAME_LEN 264
static nfc_device_t *pnd;
static nfc_device *pnd;
void stop_dep_communication (int sig)
{
@ -62,38 +62,40 @@ void stop_dep_communication (int sig)
int
main (int argc, const char *argv[])
{
nfc_target_t nt;
byte_t abtRx[MAX_FRAME_LEN];
nfc_target nt;
uint8_t abtRx[MAX_FRAME_LEN];
size_t szRx = sizeof(abtRx);
byte_t abtTx[] = "Hello World!";
uint8_t abtTx[] = "Hello World!";
if (argc > 1) {
printf ("Usage: %s\n", argv[0]);
return EXIT_FAILURE;
}
nfc_init (NULL);
pnd = nfc_connect (NULL);
pnd = nfc_open (NULL, NULL);
if (!pnd) {
printf("Unable to connect to NFC device.\n");
printf("Unable to open NFC device.\n");
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);
if (!nfc_initiator_init (pnd)) {
if (nfc_initiator_init (pnd) < 0) {
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");
goto error;
}
print_nfc_target (nt, false);
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");
goto error;
}
@ -101,9 +103,13 @@ main (int argc, const char *argv[])
abtRx[szRx] = 0;
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:
nfc_disconnect (pnd);
nfc_close (pnd);
nfc_exit (NULL);
return EXIT_SUCCESS;
}

View file

@ -47,7 +47,7 @@
#define MAX_FRAME_LEN 264
static nfc_device_t *pnd;
static nfc_device *pnd;
void stop_dep_communication (int sig)
{
@ -61,23 +61,23 @@ void stop_dep_communication (int sig)
int
main (int argc, const char *argv[])
{
byte_t abtRx[MAX_FRAME_LEN];
size_t szRx = sizeof(abtRx);
size_t szDeviceFound;
byte_t abtTx[] = "Hello Mars!";
uint8_t abtRx[MAX_FRAME_LEN];
int szRx;
uint8_t abtTx[] = "Hello Mars!";
#define MAX_DEVICE_COUNT 2
nfc_device_desc_t pnddDevices[MAX_DEVICE_COUNT];
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szDeviceFound);
nfc_connstring connstrings[MAX_DEVICE_COUNT];
size_t szDeviceFound = nfc_list_devices (NULL, connstrings, MAX_DEVICE_COUNT);
// Little hack to allow using nfc-dep-initiator & nfc-dep-target from
// the same machine: if there is more than one readers connected
// nfc-dep-target will connect to the second reader
// the same machine: if there is more than one readers opened
// nfc-dep-target will open the second reader
// (we hope they're always detected in the same order)
nfc_init (NULL);
if (szDeviceFound == 1) {
pnd = nfc_connect (&(pnddDevices[0]));
pnd = nfc_open (NULL, connstrings[0]);
} else if (szDeviceFound > 1) {
pnd = nfc_connect (&(pnddDevices[1]));
pnd = nfc_open (NULL, connstrings[1]);
} else {
printf("No device found.");
printf("No device found.\n");
return EXIT_FAILURE;
}
@ -86,7 +86,7 @@ main (int argc, const char *argv[])
return EXIT_FAILURE;
}
nfc_target_t nt = {
nfc_target nt = {
.nm = {
.nmt = NMT_DEP,
.nbr = NBR_UNDEFINED
@ -108,10 +108,10 @@ main (int argc, const char *argv[])
};
if (!pnd) {
printf("Unable to connect to NFC device.\n");
printf("Unable to open NFC device.\n");
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);
@ -119,27 +119,28 @@ main (int argc, const char *argv[])
print_nfc_target (nt, false);
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");
goto error;
}
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");
goto error;
}
abtRx[szRx] = '\0';
abtRx[(size_t) szRx] = '\0';
printf ("Received: %s\n", abtRx);
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");
goto error;
}
printf("Data sent.\n");
error:
nfc_disconnect (pnd);
nfc_close (pnd);
nfc_exit (NULL);
return EXIT_SUCCESS;
}

View file

@ -69,9 +69,9 @@
#include <nfc/nfc.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
stop_emulation (int sig)
@ -112,7 +112,7 @@ static uint8_t __nfcforum_tag2_memory_area[] = {
#define HALT 0x50
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;
@ -155,7 +155,7 @@ main(int argc, char *argv[])
(void)argc;
(void)argv;
nfc_target_t nt = {
nfc_target nt = {
.nm = {
.nmt = NMT_ISO14443A,
.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 = {
.io = nfcforum_tag2_io
.io = nfcforum_tag2_io
};
struct nfc_emulator emulator = {
.target= &nt,
.target = &nt,
.state_machine = &state_machine,
.user_data = __nfcforum_tag2_memory_area,
};
signal (SIGINT, stop_emulation);
pnd = nfc_connect (NULL);
nfc_init (NULL);
pnd = nfc_open (NULL, NULL);
if (pnd == NULL) {
ERR("Unable to connect to NFC device");
ERR("Unable to open NFC device");
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");
if (nfc_emulate_target (pnd, &emulator) < 0) {
goto error;
}
nfc_disconnect(pnd);
nfc_close(pnd);
nfc_exit (NULL);
exit (EXIT_SUCCESS);
error:
if (pnd) {
nfc_perror (pnd, argv[0]);
nfc_disconnect (pnd);
nfc_close (pnd);
nfc_exit (NULL);
}
}

View file

@ -54,9 +54,9 @@
#define MAX_FRAME_LEN (264)
#define SAK_ISO14443_4_COMPLIANT 0x20
static byte_t abtRx[MAX_FRAME_LEN];
static size_t szRx = sizeof(abtRx);
static nfc_device_t *pnd;
static uint8_t abtRx[MAX_FRAME_LEN];
static int szRx;
static nfc_device *pnd;
static bool quiet_output = false;
static bool init_mfc_auth = false;
@ -65,13 +65,14 @@ intr_hdlr (void)
{
printf ("\nQuitting...\n");
if (pnd != NULL) {
nfc_disconnect(pnd);
nfc_close(pnd);
}
nfc_exit (NULL);
exit (EXIT_FAILURE);
}
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;
*pszOutput = 0;
@ -134,31 +135,31 @@ target_io( nfc_target_t * pnt, const byte_t * pbtInput, const size_t szInput, by
}
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;
byte_t abtTx[MAX_FRAME_LEN];
uint8_t abtTx[MAX_FRAME_LEN];
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");
return false;
}
while ( loop ) {
loop = target_io( pnt, abtRx, szRx, abtTx, &szTx );
loop = target_io( pnt, abtRx, (size_t) szRx, abtTx, &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");
return false;
}
}
if ( loop ) {
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;
}
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");
return false;
}
@ -179,19 +180,21 @@ main (int argc, char *argv[])
signal (SIGINT, (void (*)()) intr_hdlr);
#endif
nfc_init (NULL);
// Try to open the NFC reader
pnd = nfc_connect (NULL);
pnd = nfc_open (NULL, NULL);
// Display libnfc version
acLibnfcVersion = nfc_version ();
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
if (pnd == NULL) {
ERR("Unable to connect to NFC device");
ERR("Unable to open NFC device");
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:
// * Only short UIDs are supported
@ -203,7 +206,7 @@ main (int argc, char *argv[])
// Example of a Mifare Classic Mini
// Note that crypto1 is not implemented in this example
nfc_target_t nt = {
nfc_target nt = {
.nm = {
.nmt = NMT_ISO14443A,
.nbr = NBR_UNDEFINED,
@ -220,40 +223,53 @@ main (int argc, char *argv[])
};
/*
// Example of a FeliCa
nfc_target_t nt = {
.nm.nmt = NMT_FELICA,
.nm.nbr = NBR_UNDEFINED,
.nti.nfi.abtId = { 0x01, 0xFE, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF },
.nti.nfi.abtPad = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF },
.nti.nfi.abtSysCode = { 0xFF, 0xFF },
nfc_target nt = {
.nm = {
.nmt = NMT_FELICA,
.nbr = NBR_UNDEFINED,
},
.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)
nfc_target_t nt = {
.nm.nmt = NMT_ISO14443A,
.nm.nbr = NBR_UNDEFINED,
.nti.nai.abtAtqa = { 0x03, 0x44 },
.nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef },
.nti.nai.btSak = 0x20,
.nti.nai.szUidLen = 4,
.nti.nai.abtAts = { 0x75, 0x77, 0x81, 0x02, 0x80 },
.nti.nai.szAtsLen = 5,
nfc_target nt = {
.nm = {
.nmt = NMT_ISO14443A,
.nbr = NBR_UNDEFINED,
},
.nti = {
.nai = {
abtAtqa = { 0x03, 0x44 },
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]);
print_nfc_iso14443a_info (nt.nti.nai, true);
// Switch off NDO_EASY_FRAMING if target is not ISO14443-4
nfc_configure (pnd, NDO_EASY_FRAMING, (nt.nti.nai.btSak & SAK_ISO14443_4_COMPLIANT));
// Switch off NP_EASY_FRAMING if target is not ISO14443-4
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");
if (!nfc_target_emulate_tag (pnd, &nt)) {
nfc_perror (pnd, "nfc_target_emulate_tag");
exit (EXIT_FAILURE);
}
nfc_disconnect(pnd);
nfc_close(pnd);
nfc_exit (NULL);
exit (EXIT_SUCCESS);
}

View file

@ -56,14 +56,14 @@
#define MAX_FRAME_LEN 264
static byte_t abtRecv[MAX_FRAME_LEN];
static size_t szRecvBits;
static nfc_device_t *pnd;
static uint8_t abtRecv[MAX_FRAME_LEN];
static int szRecvBits;
static nfc_device *pnd;
// ISO14443A Anti-Collision response
byte_t abtAtqa[2] = { 0x04, 0x00 };
byte_t abtUidBcc[5] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x62 };
byte_t abtSak[9] = { 0x08, 0xb6, 0xdd };
uint8_t abtAtqa[2] = { 0x04, 0x00 };
uint8_t abtUidBcc[5] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x62 };
uint8_t abtSak[9] = { 0x08, 0xb6, 0xdd };
void
intr_hdlr (void)
@ -88,7 +88,7 @@ print_usage (char *argv[])
int
main (int argc, char *argv[])
{
byte_t *pbtTx = NULL;
uint8_t *pbtTx = NULL;
size_t szTxBits;
bool quiet_output = false;
@ -104,12 +104,12 @@ main (int argc, char *argv[])
printf ("Quiet mode.\n");
quiet_output = true;
} 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]);
abtUidBcc[4] = 0x00;
for (i = 0; i < 4; ++i) {
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];
}
} else {
@ -125,22 +125,24 @@ main (int argc, char *argv[])
signal (SIGINT, (void (*)()) intr_hdlr);
#endif
nfc_init (NULL);
// Try to open the NFC device
pnd = nfc_connect (NULL);
pnd = nfc_open (NULL, NULL);
if (pnd == NULL) {
printf ("Unable to connect to NFC device\n");
printf ("Unable to open NFC device\n");
exit(EXIT_FAILURE);
}
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 ("[+] 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");
// Note: We have to build a "fake" nfc_target_t in order to do exactly the same that was done before the new nfc_target_init() was introduced.
nfc_target_t nt = {
// 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 nt = {
.nm = {
.nmt = NMT_ISO14443A,
.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");
ERR ("Could not come out of auto-emulation, no command was received");
goto error;
}
printf ("[+] Received initiator command: ");
print_hex_bits (abtRecv, szRecvBits);
print_hex_bits (abtRecv, (size_t) szRecvBits);
printf ("[+] Configuring communication\n");
if (!nfc_configure (pnd, NDO_HANDLE_CRC, false) || !nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
nfc_perror (pnd, "nfc_configure");
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_device_set_property_bool");
exit (EXIT_FAILURE);
}
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) {
// 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
switch (szRecvBits) {
case 7: // Request or Wakeup
@ -200,12 +202,12 @@ main (int argc, char *argv[])
if (!quiet_output) {
printf ("R: ");
print_hex_bits (abtRecv, szRecvBits);
print_hex_bits (abtRecv, (size_t) szRecvBits);
}
// Test if we know how to respond
if (szTxBits) {
// 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");
goto error;
}
@ -216,10 +218,12 @@ main (int argc, char *argv[])
}
}
}
nfc_disconnect (pnd);
nfc_close (pnd);
nfc_exit (NULL);
exit (EXIT_SUCCESS);
error:
nfc_disconnect (pnd);
nfc_close (pnd);
nfc_exit (NULL);
exit (EXIT_FAILURE);
}

View file

@ -1,6 +1,6 @@
.TH nfc-poll 1 "June 26, 2009" "libnfc" "libnfc's examples"
.SH NAME
nfc-poll \- Poll for one NFC target
nfc-poll \- poll first available NFC target
.SH SYNOPSIS
.B nfc-poll
.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)
using ISO14443-A, FeliCa, Jewel and ISO14443-B modulations.
This tool relies on a hardware polling feature of the PN532, it will display
available information retrieved from the tag.
This tool uses hardware polling feature if available (ie. PN532) or switch back
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
There are some well-know limits with this example:

View file

@ -51,7 +51,7 @@
#define MAX_DEVICE_COUNT 16
static nfc_device_t *pnd = NULL;
static nfc_device *pnd = NULL;
void stop_polling (int sig)
{
@ -62,80 +62,76 @@ void stop_polling (int sig)
exit (EXIT_FAILURE);
}
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[])
{
size_t szFound;
size_t i;
bool verbose = false;
nfc_device_desc_t *pnddDevices;
signal (SIGINT, stop_polling);
pnddDevices = parse_args (argc, argv, &szFound, &verbose);
// Display libnfc version
const char *acLibnfcVersion = nfc_version ();
if (argc > 1) {
errx (1, "usage: %s", argv[0]);
}
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
if (szFound == 0) {
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
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 );
if (argc != 1) {
if ((argc == 2) && (0 == strcmp ("-v", argv[1]))) {
verbose = true;
} else {
if (pnd->iLastError) {
nfc_perror (pnd, "nfc_initiator_poll_targets");
nfc_disconnect (pnd);
exit (EXIT_FAILURE);
} else {
printf ("No target found.\n");
}
print_usage (argv[0]);
exit (EXIT_FAILURE);
}
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);
}

View file

@ -50,14 +50,14 @@
#define MAX_FRAME_LEN 264
#define MAX_DEVICE_COUNT 2
static byte_t abtReaderRx[MAX_FRAME_LEN];
static byte_t abtReaderRxPar[MAX_FRAME_LEN];
static size_t szReaderRxBits;
static byte_t abtTagRx[MAX_FRAME_LEN];
static byte_t abtTagRxPar[MAX_FRAME_LEN];
static size_t szTagRxBits;
static nfc_device_t *pndReader;
static nfc_device_t *pndTag;
static uint8_t abtReaderRx[MAX_FRAME_LEN];
static uint8_t abtReaderRxPar[MAX_FRAME_LEN];
static int szReaderRxBits;
static uint8_t abtTagRx[MAX_FRAME_LEN];
static uint8_t abtTagRxPar[MAX_FRAME_LEN];
static int szTagRxBits;
static nfc_device *pndReader;
static nfc_device *pndTag;
static bool quitting = false;
void
@ -82,8 +82,6 @@ main (int argc, char *argv[])
{
int arg;
bool quiet_output = false;
size_t szFound;
nfc_device_desc_t *pnddDevices;
const char *acLibnfcVersion = nfc_version ();
// Get commandline options
@ -109,33 +107,32 @@ main (int argc, char *argv[])
signal (SIGINT, (void (*)()) intr_hdlr);
#endif
// Allocate memory to put the result of available devices listing
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
fprintf (stderr, "malloc() failed\n");
return EXIT_FAILURE;
}
nfc_connstring connstrings[MAX_DEVICE_COUNT];
// 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) {
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;
}
nfc_init (NULL);
// Try to open the NFC emulator device
pndTag = nfc_connect (&(pnddDevices[0]));
pndTag = nfc_open (NULL, connstrings[0]);
if (pndTag == NULL) {
printf ("Error connecting NFC emulator device\n");
printf ("Error opening NFC emulator device\n");
return EXIT_FAILURE;
}
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 ("[+] 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");
nfc_target_t nt = {
nfc_target nt = {
.nm = {
.nmt = NMT_ISO14443A,
.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");
nfc_disconnect (pndTag);
nfc_close (pndTag);
nfc_exit (NULL);
return EXIT_FAILURE;
}
printf ("%s", "Configuring emulator settings...");
if (!nfc_configure (pndTag, NDO_HANDLE_CRC, false) ||
!nfc_configure (pndTag, NDO_HANDLE_PARITY, false) || !nfc_configure (pndTag, NDO_ACCEPT_INVALID_FRAMES, true)) {
nfc_perror (pndTag, "nfc_configure");
if ((nfc_device_set_property_bool (pndTag, NP_HANDLE_CRC, false) < 0) ||
(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_device_set_property_bool");
exit (EXIT_FAILURE);
}
printf ("%s", "Done, emulated tag is initialized");
// 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...");
nfc_initiator_init (pndReader);
if (!nfc_configure (pndReader, NDO_HANDLE_CRC, false) ||
!nfc_configure (pndReader, NDO_HANDLE_PARITY, false) ||
!nfc_configure (pndReader, NDO_ACCEPT_INVALID_FRAMES, true)) {
nfc_perror (pndReader, "nfc_configure");
if (nfc_initiator_init (pndReader) < 0) {
nfc_perror (pndReader, "nfc_initiator_init");
exit (EXIT_FAILURE);
}
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);
}
printf ("%s", "Done, relaying frames now!");
while (!quitting) {
// 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
if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26) {
// Drop down field for a very short time (original tag will reboot)
if (!nfc_configure (pndReader, NDO_ACTIVATE_FIELD, false)) {
nfc_perror (pndReader, "nfc_configure");
if (nfc_device_set_property_bool (pndReader, NP_ACTIVATE_FIELD, false) < 0) {
nfc_perror (pndReader, "nfc_device_set_property_bool");
exit (EXIT_FAILURE);
}
if (!quiet_output)
printf ("\n");
if (!nfc_configure (pndReader, NDO_ACTIVATE_FIELD, true)) {
nfc_perror (pndReader, "nfc_configure");
if (nfc_device_set_property_bool (pndReader, NP_ACTIVATE_FIELD, true) < 0) {
nfc_perror (pndReader, "nfc_device_set_property_bool");
exit (EXIT_FAILURE);
}
}
// Print the reader frame to the screen
if (!quiet_output) {
printf ("R: ");
print_hex_par (abtReaderRx, szReaderRxBits, abtReaderRxPar);
print_hex_par (abtReaderRx, (size_t) szReaderRxBits, abtReaderRxPar);
}
// Forward the frame to the original tag
if (nfc_initiator_transceive_bits
(pndReader, abtReaderRx, szReaderRxBits, abtReaderRxPar, abtTagRx, &szTagRxBits, abtTagRxPar)) {
if ((szTagRxBits = nfc_initiator_transceive_bits
(pndReader, abtReaderRx, (size_t) szReaderRxBits, abtReaderRxPar, abtTagRx, abtTagRxPar)) > 0) {
// 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");
exit (EXIT_FAILURE);
}
@ -217,7 +219,8 @@ main (int argc, char *argv[])
}
}
nfc_disconnect (pndTag);
nfc_disconnect (pndReader);
nfc_close (pndTag);
nfc_close (pndReader);
nfc_exit (NULL);
exit (EXIT_SUCCESS);
}

View file

@ -52,49 +52,48 @@
int
main (int argc, const char *argv[])
{
size_t szFound;
size_t i;
nfc_device_t *pnd;
nfc_device_desc_t *pnddDevices;
nfc_device *pnd;
const char *acLibnfcVersion;
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);
const byte_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 byte_t pncmd_diagnose_ram_test[] = { Diagnose, 0x02 };
const uint8_t pncmd_diagnose_communication_line_test[] = { Diagnose, 0x00, 0x06, 'l', 'i', 'b', 'n', 'f', 'c' };
const uint8_t pncmd_diagnose_rom_test[] = { Diagnose, 0x01 };
const uint8_t pncmd_diagnose_ram_test[] = { Diagnose, 0x02 };
if (argc > 1) {
errx (1, "usage: %s", argv[0]);
}
nfc_init (NULL);
// Display libnfc version
acLibnfcVersion = nfc_version ();
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
fprintf (stderr, "malloc() failed\n");
return EXIT_FAILURE;
}
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound);
nfc_connstring connstrings[MAX_DEVICE_COUNT];
size_t szFound = nfc_list_devices (NULL, connstrings, MAX_DEVICE_COUNT);
if (szFound == 0) {
printf ("No NFC device found.\n");
}
for (i = 0; i < szFound; i++) {
pnd = nfc_connect (&(pnddDevices[i]));
pnd = nfc_open (NULL, connstrings[i]);
if (pnd == NULL) {
ERR ("%s", "Unable to connect to NFC device.");
ERR ("%s", "Unable to open NFC device.");
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);
if (result) {
res = pn53x_transceive (pnd, pncmd_diagnose_communication_line_test, sizeof (pncmd_diagnose_communication_line_test), abtRx, szRx, 0);
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 = (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);
@ -103,16 +102,18 @@ main (int argc, const char *argv[])
}
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);
if (result) {
res = pn53x_transceive (pnd, pncmd_diagnose_rom_test, sizeof (pncmd_diagnose_rom_test), abtRx, szRx, 0);
if (res > 0) {
szRx = (size_t) res;
result = ((szRx == 1) && (abtRx[0] == 0x00));
} else {
nfc_perror (pnd, "pn53x_transceive");
}
printf (" ROM test: %s\n", result ? "OK" : "Failed");
result = pn53x_transceive (pnd, pncmd_diagnose_ram_test, sizeof (pncmd_diagnose_ram_test), abtRx, &szRx, NULL);
if (result) {
res = pn53x_transceive (pnd, pncmd_diagnose_ram_test, sizeof (pncmd_diagnose_ram_test), abtRx, szRx, 0);
if (res > 0) {
szRx = (size_t) res;
result = ((szRx == 1) && (abtRx[0] == 0x00));
} else {
nfc_perror (pnd, "pn53x_transceive");

View file

@ -72,24 +72,26 @@ wait_one_minute (void)
int
main (int argc, const char *argv[])
{
nfc_device_t *pnd;
nfc_device *pnd;
(void) argc;
(void) argv;
nfc_init (NULL);
// Display libnfc version
const char *acLibnfcVersion = nfc_version ();
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
// Connect using the first available NFC device
pnd = nfc_connect (NULL);
// Open using the first available NFC device
pnd = nfc_open (NULL, NULL);
if (pnd == NULL) {
ERR ("%s", "Unable to connect to NFC device.");
ERR ("%s", "Unable to open NFC device.");
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
printf ("\nSelect the communication mode:\n");
@ -110,7 +112,7 @@ main (int argc, const char *argv[])
// Connect with the SAM
// FIXME: Its a private pn53x function
if (!pn53x_SAMConfiguration (pnd, mode, NULL)) {
if (pn53x_SAMConfiguration (pnd, mode, 0) < 0) {
nfc_perror (pnd, "pn53x_SAMConfiguration");
exit (EXIT_FAILURE);
}
@ -125,22 +127,25 @@ main (int argc, const char *argv[])
case PSM_WIRED_CARD:
{
nfc_target_t nt;
nfc_target nt;
// Set connected NFC device to initiator mode
nfc_initiator_init (pnd);
// Set opened NFC device to initiator mode
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
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
nfc_perror (pnd, "nfc_configure");
if (nfc_device_set_property_bool (pnd, NP_INFINITE_SELECT, false) < 0) {
nfc_perror (pnd, "nfc_device_set_property_bool");
exit (EXIT_FAILURE);
}
// Read the SAM's info
const nfc_modulation_t nmSAM = {
const nfc_modulation nmSAM = {
.nmt = NMT_ISO14443A,
.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");
ERR ("%s", "Reading of SAM info failed.");
exit (EXIT_FAILURE);
@ -153,10 +158,9 @@ main (int argc, const char *argv[])
case PSM_DUAL_CARD:
{
byte_t abtRx[MAX_FRAME_LEN];
size_t szRx = sizeof(abtRx);
uint8_t abtRx[MAX_FRAME_LEN];
nfc_target_t nt = {
nfc_target nt = {
.nm = {
.nmt = NMT_ISO14443A,
.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 ("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");
return EXIT_FAILURE;
}
@ -185,10 +189,11 @@ main (int argc, const char *argv[])
}
// Disconnect from the SAM
pn53x_SAMConfiguration (pnd, PSM_NORMAL, NULL);
pn53x_SAMConfiguration (pnd, PSM_NORMAL, 0);
// Disconnect from NFC device
nfc_disconnect (pnd);
// Close NFC device
nfc_close (pnd);
nfc_exit (NULL);
exit (EXIT_SUCCESS);
}

View file

@ -71,41 +71,46 @@
int main(int argc, const char* argv[])
{
nfc_device_t* pnd;
byte_t abtRx[MAX_FRAME_LEN];
byte_t abtTx[MAX_FRAME_LEN];
nfc_device *pnd;
uint8_t abtRx[MAX_FRAME_LEN];
uint8_t abtTx[MAX_FRAME_LEN];
size_t szRx = sizeof(abtRx);
size_t szTx;
extern FILE* stdin;
FILE* input = NULL;
if (argc >= 2) {
if((input=fopen(argv[1], "r"))==NULL) {
if((input = fopen(argv[1], "r"))==NULL) {
ERR ("%s", "Cannot open file.");
return EXIT_FAILURE;
}
}
nfc_init (NULL);
// Try to open the NFC reader
pnd = nfc_connect(NULL);
pnd = nfc_open(NULL, NULL);
if (pnd == NULL) {
ERR ("%s", "Unable to connect to NFC device.");
ERR ("%s", "Unable to open NFC device.");
return EXIT_FAILURE;
}
printf ("Connected to NFC reader: %s\n", pnd->acName);
nfc_initiator_init(pnd);
printf ("NFC reader: %s opened\n", nfc_device_get_name (pnd));
if (nfc_initiator_init (pnd) < 0) {
nfc_perror (pnd, "nfc_initiator_init");
exit (EXIT_FAILURE);
}
char * cmd;
char * prompt="> ";
char *cmd;
char *prompt = "> ";
while(1) {
int offset=0;
int offset = 0;
#if defined(HAVE_READLINE)
if (input==NULL) { // means we use stdin
cmd=readline(prompt);
if (input == NULL) { // means we use stdin
cmd = readline(prompt);
// NULL if ctrl-d
if (cmd==NULL) {
if (cmd == NULL) {
printf("Bye!\n");
break;
}
@ -113,7 +118,7 @@ int main(int argc, const char* argv[])
} else {
#endif //HAVE_READLINE
size_t n = 255;
char * ret = NULL;
char *ret = NULL;
cmd = malloc(n);
printf("%s", prompt);
fflush(0);
@ -132,18 +137,18 @@ int main(int argc, const char* argv[])
#if defined(HAVE_READLINE)
}
#endif //HAVE_READLINE
if (cmd[0]=='q') {
if (cmd[0] == 'q') {
printf("Bye!\n");
free(cmd);
break;
}
if (cmd[0]=='p') {
int s=0;
if (cmd[0] == 'p') {
int s = 0;
offset++;
while (isspace(cmd[offset])) {
offset++;
}
sscanf(cmd+offset, "%d", &s);
sscanf(cmd + offset, "%d", &s);
printf("Pause for %i msecs\n", s);
if (s>0) {
sleep(s * SUSP_TIME);
@ -152,14 +157,14 @@ int main(int argc, const char* argv[])
continue;
}
szTx = 0;
for(int i = 0; i<MAX_FRAME_LEN-10; i++) {
for(int i = 0; i < MAX_FRAME_LEN - 10; i++) {
int size;
byte_t byte;
uint8_t byte;
while (isspace(cmd[offset])) {
offset++;
}
size = sscanf(cmd+offset, "%2x", (unsigned int*)&byte);
if (size<1) {
if (size < 1 ) {
break;
}
abtTx[i] = byte;
@ -175,14 +180,16 @@ int main(int argc, const char* argv[])
continue;
}
printf("Tx: ");
print_hex((byte_t*)abtTx,szTx);
print_hex((uint8_t*)abtTx,szTx);
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);
nfc_perror (pnd, "Rx");
continue;
}
szRx = (size_t) res;
printf("Rx: ");
print_hex(abtRx, szRx);
@ -192,6 +199,7 @@ int main(int argc, const char* argv[])
if (input != NULL) {
fclose(input);
}
nfc_disconnect(pnd);
nfc_close(pnd);
nfc_exit (NULL);
return 1;
}

View file

@ -32,17 +32,17 @@ struct nfc_emulation_state_machine;
struct nfc_emulator {
nfc_target_t *target;
nfc_target *target;
struct nfc_emulation_state_machine *state_machine;
void *user_data;
};
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;
};
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
}

View file

@ -32,80 +32,48 @@
# include <stdbool.h>
# include <stdio.h>
typedef uint8_t byte_t;
# define DEVICE_NAME_LENGTH 256
# define DEVICE_PORT_LENGTH 64
typedef void *nfc_context;
/**
* @struct nfc_device_t
* @brief NFC device information
* NFC device
*/
typedef struct {
/** 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;
typedef struct nfc_device nfc_device;
/**
* @struct nfc_device_desc_t
* @brief NFC device description
*
* This struct is used to try to connect to a specified nfc device when nfc_connect(...)
* Connection string
*/
typedef struct {
/** 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)
typedef char nfc_connstring[1024];
/**
* @enum nfc_device_option_t
* @brief NFC device option
* Properties
*/
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
* bytes from received frames as incoming CRC bytes. They will be verified
* against the used modulation and protocol. If an frame is expected with
* incorrect CRC bytes this option should be disabled. Example frames where
* this is useful are the ATQA and UID+BCC that are transmitted without CRC
* bytes during the anti-collision phase of the ISO14443-A protocol. */
NDO_HANDLE_CRC = 0x00,
NP_HANDLE_CRC,
/** Parity bits in the network layer of ISO14443-A are by default generated and
* validated in the PN53X chip. This is a very convenient feature. On certain
* times though it is useful to get full control of the transmitted data. The
@ -113,31 +81,31 @@ typedef enum {
* parity bits. For interoperability it is required to be completely
* compatible, including the arbitrary parity bits. When this option is
* disabled, the functions to communicating bits should be used. */
NDO_HANDLE_PARITY = 0x01,
NP_HANDLE_PARITY,
/** This option can be used to enable or disable the electronic field of the
* NFC device. */
NDO_ACTIVATE_FIELD = 0x10,
NP_ACTIVATE_FIELD,
/** The internal CRYPTO1 co-processor can be used to transmit messages
* encrypted. This option is automatically activated after a successful MIFARE
* Classic authentication. */
NDO_ACTIVATE_CRYPTO1 = 0x11,
NP_ACTIVATE_CRYPTO1,
/** The default configuration defines that the PN53X chip will try indefinitely
* to invite a tag in the field to respond. This could be desired when it is
* certain a tag will enter the field. On the other hand, when this is
* uncertain, it will block the application. This option could best be compared
* to the (NON)BLOCKING option used by (socket)network programming. */
NDO_INFINITE_SELECT = 0x20,
NP_INFINITE_SELECT,
/** If this option is enabled, frames that carry less than 4 bits are allowed.
* According to the standards these frames should normally be handles as
* invalid frames. */
NDO_ACCEPT_INVALID_FRAMES = 0x30,
NP_ACCEPT_INVALID_FRAMES,
/** If the NFC device should only listen to frames, it could be useful to let
* it gather multiple frames in a sequence. They will be stored in the internal
* FIFO of the PN53X chip. This could be retrieved by using the receive data
* functions. Note that if the chip runs out of bytes (FIFO = 64 bytes long),
* it will overwrite the first received frames, so quick retrieving of the
* received data is desirable. */
NDO_ACCEPT_MULTIPLE_FRAMES = 0x31,
NP_ACCEPT_MULTIPLE_FRAMES,
/** This option can be used to enable or disable the auto-switching mode to
* ISO14443-4 is device is compliant.
* In initiator mode, it means that NFC chip will send RATS automatically when
@ -145,151 +113,154 @@ typedef enum {
* requested.
* In target mode, with a NFC chip compiliant (ie. PN532), the chip will
* emulate a 14443-4 PICC using hardware capability */
NDO_AUTO_ISO14443_4 = 0x40,
NP_AUTO_ISO14443_4,
/** Use automatic frames encapsulation and chaining. */
NDO_EASY_FRAMING = 0x41,
NP_EASY_FRAMING,
/** 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 */
NDO_FORCE_ISO14443_B = 0x43,
NP_FORCE_ISO14443_B,
/** Force the chip to run at 106 kbps */
NDO_FORCE_SPEED_106 = 0x50,
} nfc_device_option_t;
NP_FORCE_SPEED_106,
} 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
*/
typedef enum {
NDM_UNDEFINED = 0,
NDM_PASSIVE,
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)
*/
typedef struct {
/** NFCID3 */
byte_t abtNFCID3[10];
uint8_t abtNFCID3[10];
/** DID */
byte_t btDID;
uint8_t btDID;
/** Supported send-bit rate */
byte_t btBS;
uint8_t btBS;
/** Supported receive-bit rate */
byte_t btBR;
uint8_t btBR;
/** Timeout value */
byte_t btTO;
uint8_t btTO;
/** PP Parameters */
byte_t btPP;
uint8_t btPP;
/** General Bytes */
byte_t abtGB[48];
uint8_t abtGB[48];
size_t szGB;
/** DEP mode */
nfc_dep_mode_t ndm;
} nfc_dep_info_t;
nfc_dep_mode ndm;
} nfc_dep_info;
/**
* @struct nfc_iso14443a_info_t
* @struct nfc_iso14443a_info
* @brief NFC ISO14443A tag (MIFARE) information
*/
typedef struct {
byte_t abtAtqa[2];
byte_t btSak;
uint8_t abtAtqa[2];
uint8_t btSak;
size_t szUidLen;
byte_t abtUid[10];
uint8_t abtUid[10];
size_t szAtsLen;
byte_t abtAts[254]; // Maximal theoretical ATS is FSD-2, FSD=256 for FSDI=8 in RATS
} nfc_iso14443a_info_t;
uint8_t abtAts[254]; // Maximal theoretical ATS is FSD-2, FSD=256 for FSDI=8 in RATS
} nfc_iso14443a_info;
/**
* @struct nfc_felica_info_t
* @struct nfc_felica_info
* @brief NFC FeLiCa tag information
*/
typedef struct {
size_t szLen;
byte_t btResCode;
byte_t abtId[8];
byte_t abtPad[8];
byte_t abtSysCode[2];
} nfc_felica_info_t;
uint8_t btResCode;
uint8_t abtId[8];
uint8_t abtPad[8];
uint8_t abtSysCode[2];
} nfc_felica_info;
/**
* @struct nfc_iso14443b_info_t
* @struct nfc_iso14443b_info
* @brief NFC ISO14443B tag information
*/
typedef struct {
/** 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) */
byte_t abtApplicationData[4];
uint8_t abtApplicationData[4];
/** 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 */
uint8_t ui8CardIdentifier;
} nfc_iso14443b_info_t;
} nfc_iso14443b_info;
/**
* @struct nfc_iso14443bi_info_t
* @struct nfc_iso14443bi_info
* @brief NFC ISO14443B' tag information
*/
typedef struct {
/** DIV: 4 LSBytes of tag serial number */
byte_t abtDIV[4];
uint8_t abtDIV[4];
/** Software version & type of REPGEN */
byte_t btVerLog;
uint8_t btVerLog;
/** Config Byte, present if long REPGEN */
byte_t btConfig;
uint8_t btConfig;
/** ATR, if any */
size_t szAtrLen;
byte_t abtAtr[33];
} nfc_iso14443bi_info_t;
uint8_t abtAtr[33];
} nfc_iso14443bi_info;
/**
* @struct nfc_iso14443b2sr_info_t
* @struct nfc_iso14443b2sr_info
* @brief NFC ISO14443-2B ST SRx tag information
*/
typedef struct {
byte_t abtUID[8];
} nfc_iso14443b2sr_info_t;
uint8_t abtUID[8];
} nfc_iso14443b2sr_info;
/**
* @struct nfc_iso14443b2ct_info_t
* @struct nfc_iso14443b2ct_info
* @brief NFC ISO14443-2B ASK CTx tag information
*/
typedef struct {
byte_t abtUID[4];
byte_t btProdCode;
byte_t btFabCode;
} nfc_iso14443b2ct_info_t;
uint8_t abtUID[4];
uint8_t btProdCode;
uint8_t btFabCode;
} nfc_iso14443b2ct_info;
/**
* @struct nfc_jewel_info_t
* @struct nfc_jewel_info
* @brief NFC Jewel tag information
*/
typedef struct {
byte_t btSensRes[2];
byte_t btId[4];
} nfc_jewel_info_t;
uint8_t btSensRes[2];
uint8_t btId[4];
} nfc_jewel_info;
/**
* @union nfc_target_info_t
* @union nfc_target_info
* @brief Union between all kind of tags information structures.
*/
typedef union {
nfc_iso14443a_info_t nai;
nfc_felica_info_t nfi;
nfc_iso14443b_info_t nbi;
nfc_iso14443bi_info_t nii;
nfc_iso14443b2sr_info_t nsi;
nfc_iso14443b2ct_info_t nci;
nfc_jewel_info_t nji;
nfc_dep_info_t ndi;
} nfc_target_info_t;
nfc_iso14443a_info nai;
nfc_felica_info nfi;
nfc_iso14443b_info nbi;
nfc_iso14443bi_info nii;
nfc_iso14443b2sr_info nsi;
nfc_iso14443b2ct_info nci;
nfc_jewel_info nji;
nfc_dep_info ndi;
} nfc_target_info;
/**
* @enum nfc_baud_rate_t
* @enum nfc_baud_rate
* @brief NFC baud rate enumeration
*/
typedef enum {
@ -298,10 +269,10 @@ typedef enum {
NBR_212,
NBR_424,
NBR_847,
} nfc_baud_rate_t;
} nfc_baud_rate;
/**
* @enum nfc_modulation_type_t
* @enum nfc_modulation_type
* @brief NFC modulation type enumeration
*/
typedef enum {
@ -313,25 +284,25 @@ typedef enum {
NMT_ISO14443B2CT, // ISO14443-2B ASK CTx
NMT_FELICA,
NMT_DEP,
} nfc_modulation_type_t;
} nfc_modulation_type;
/**
* @struct nfc_modulation_t
* @struct nfc_modulation
* @brief NFC modulation structure
*/
typedef struct {
nfc_modulation_type_t nmt;
nfc_baud_rate_t nbr;
} nfc_modulation_t;
nfc_modulation_type nmt;
nfc_baud_rate nbr;
} nfc_modulation;
/**
* @struct nfc_target_t
* @struct nfc_target
* @brief NFC target structure
*/
typedef struct {
nfc_target_info_t nti;
nfc_modulation_t nm;
} nfc_target_t;
nfc_target_info nti;
nfc_modulation nm;
} nfc_target;
// Reset struct alignment to default
# pragma pack()

View file

@ -62,91 +62,71 @@
extern "C" {
# 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_EXPORT nfc_device_t *nfc_connect (nfc_device_desc_t * pndd);
NFC_EXPORT void nfc_disconnect (nfc_device_t * pnd);
NFC_EXPORT bool nfc_abort_command (nfc_device_t * pnd);
NFC_EXPORT void nfc_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
NFC_EXPORT bool nfc_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
NFC_EXPORT bool nfc_idle (nfc_device_t * pnd);
NFC_EXPORT bool nfc_get_default_device (nfc_connstring *connstring);
NFC_EXPORT nfc_device *nfc_open (nfc_context *context, const nfc_connstring connstring);
NFC_EXPORT void nfc_close (nfc_device *pnd);
NFC_EXPORT int nfc_abort_command (nfc_device *pnd);
NFC_EXPORT size_t nfc_list_devices (nfc_context *context, nfc_connstring connstrings[], size_t connstrings_len);
NFC_EXPORT int nfc_idle (nfc_device *pnd);
/* NFC initiator: act as "reader" */
NFC_EXPORT bool nfc_initiator_init (nfc_device_t * 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 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 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 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 bool nfc_initiator_deselect_target (nfc_device_t * pnd);
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 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 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 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_init (nfc_device *pnd);
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 int nfc_initiator_list_passive_targets (nfc_device *pnd, const nfc_modulation nm, nfc_target ant[], const size_t szTargets);
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 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 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 int nfc_initiator_deselect_target (nfc_device *pnd);
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 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 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_EXPORT bool nfc_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx);
NFC_EXPORT bool nfc_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, struct timeval *timout);
NFC_EXPORT bool nfc_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx, struct timeval *timout);
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 bool nfc_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
NFC_EXPORT int nfc_target_init (nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRx, int timeout);
NFC_EXPORT int nfc_target_send_bytes (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int timeout);
NFC_EXPORT int nfc_target_receive_bytes (nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, int timeout);
NFC_EXPORT int nfc_target_send_bits (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar);
NFC_EXPORT int nfc_target_receive_bits (nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar);
/* Error reporting */
NFC_EXPORT const char *nfc_strerror (const nfc_device_t * pnd);
NFC_EXPORT int nfc_strerror_r (const nfc_device_t * pnd, char *pcStrErrBuf, size_t szBufLen);
NFC_EXPORT void nfc_perror (const nfc_device_t * pnd, const char *pcString);
NFC_EXPORT const char *nfc_strerror (const nfc_device *pnd);
NFC_EXPORT int nfc_strerror_r (const nfc_device *pnd, char *buf, size_t buflen);
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 */
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 */
NFC_EXPORT void iso14443a_crc (byte_t * pbtData, size_t szLen, byte_t * pbtCrc);
NFC_EXPORT void iso14443a_crc_append (byte_t * pbtData, size_t szLen);
NFC_EXPORT byte_t * iso14443a_locate_historical_bytes (byte_t * pbtAts, size_t szAts, size_t * pszTk);
NFC_EXPORT void iso14443a_crc (uint8_t *pbtData, size_t szLen, uint8_t *pbtCrc);
NFC_EXPORT void iso14443a_crc_append (uint8_t *pbtData, size_t szLen);
NFC_EXPORT uint8_t *iso14443a_locate_historical_bytes (uint8_t *pbtAts, size_t szAts, size_t *pszTk);
NFC_EXPORT const char *nfc_version (void);
/* PN53x specific errors */
// TODO: Be not PN53x-specific here
#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
/* 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 */
/* Error codes */
#define NFC_SUCCESS 0 // No error
#define NFC_EIO -1 // Input / output error, device will not be usable anymore
#define NFC_EINVARG -2 // Invalid argument(s)
#define NFC_EDEVNOTSUPP -3 // Operation not supported by device
#define NFC_ENOTSUCHDEV -4 // No such device
#define NFC_EOVFLOW -5 // Buffer overflow
#define NFC_ETIMEOUT -6 // Operation timed out
#define NFC_EOPABORTED -7 // Operation aborted (by user)
#define NFC_ENOTIMPL -8 // Not (yet) implemented
#define NFC_ETGRELEASED -10 // Target released
#define NFC_ERFTRANS -20 // Error while RF transmission
#define NFC_ECHIP -90 // Device's internal chip error
# ifdef __cplusplus
}

View file

@ -18,7 +18,7 @@ libnfc_la_SOURCES = \
nfc-emulation.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_LIBADD = \
$(top_builddir)/libnfc/chips/libnfcchips.la \
@ -35,11 +35,11 @@ if LIBUSB_ENABLED
libnfc_la_LIBADD += @libusb_LIBS@
endif
if HAS_LOG4C
libnfc_la_CFLAGS += @log4c_CFLAGS@
libnfc_la_LIBADD += @log4c_LIBS@
libnfc_la_SOURCES += log.c
if WITH_DEBUG
libnfc_la_SOURCES += log-printf.c
endif
EXTRA_DIST = CMakeLists.txt
EXTRA_DIST = \
CMakeLists.txt \
log-printf.c

View file

@ -9,7 +9,3 @@ libnfcbuses_la_CFLAGS = -I$(top_srcdir)/libnfc
EXTRA_DIST = uart_posix.c uart_win32.c
if HAS_LOG4C
libnfcbuses_la_CFLAGS += @log4c_CFLAGS@
libnfcbuses_la_LIBADD = @log4c_LIBS@
endif

View file

@ -49,8 +49,8 @@ void uart_flush_input (const serial_port sp);
void uart_set_speed (serial_port sp, const uint32_t uiPortSpeed);
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_send (serial_port sp, const byte_t * pbtTx, const size_t szTx, 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 uint8_t *pbtTx, const size_t szTx, int timeout);
char **uart_list_ports (void);

View file

@ -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
# define CCLAIMED 0x80000000
typedef struct {
struct serial_port_unix{
int fd; // Serial port file descriptor
struct termios termios_backup; // Terminal info before using the port
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);
serial_port
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)
return INVALID_SERIAL_PORT;
@ -114,12 +116,12 @@ void
uart_flush_input (serial_port sp)
{
// 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
// Retrieve the count of the incoming bytes
int available_bytes_count = 0;
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) {
return;
}
@ -128,7 +130,7 @@ uart_flush_input (serial_port sp)
}
char* rx = malloc (available_bytes_count);
// 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);
free (rx);
}
@ -137,8 +139,7 @@ void
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);
serial_port_unix *spu = (serial_port_unix *) sp;
// Portability note: on some systems, B9600 != 9600 so we have to do
// uint32_t <=> speed_t associations by hand.
speed_t stPortSpeed = B9600;
@ -179,9 +180,9 @@ uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
};
// Set port speed (Input and Output)
cfsetispeed (&(spu->termios_new), stPortSpeed);
cfsetospeed (&(spu->termios_new), stPortSpeed);
if (tcsetattr (spu->fd, TCSADRAIN, &(spu->termios_new)) == -1) {
cfsetispeed (&(UART_DATA(sp)->termios_new), stPortSpeed);
cfsetospeed (&(UART_DATA(sp)->termios_new), stPortSpeed);
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.");
}
}
@ -190,8 +191,7 @@ uint32_t
uart_get_speed (serial_port sp)
{
uint32_t uiPortSpeed = 0;
const serial_port_unix *spu = (serial_port_unix *) sp;
switch (cfgetispeed (&spu->termios_new)) {
switch (cfgetispeed (&UART_DATA(sp)->termios_new)) {
case B9600:
uiPortSpeed = 9600;
break;
@ -229,10 +229,10 @@ uart_get_speed (serial_port sp)
void
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)
tcsetattr (((serial_port_unix *) sp)->fd, TCSANOW, &((serial_port_unix *) sp)->termios_backup);
close (((serial_port_unix *) sp)->fd);
tcsetattr (UART_DATA(sp)->fd, TCSANOW, &UART_DATA(sp)->termios_backup);
close (UART_DATA(sp)->fd);
}
free (sp);
}
@ -249,7 +249,7 @@ uart_close (const serial_port sp)
* @return 0 on success, otherwise driver error code
*/
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 received_bytes_count = 0;
@ -261,23 +261,19 @@ uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx, void * abort_p,
select:
// Reset file descriptor
FD_ZERO (&rfds);
FD_SET (((serial_port_unix *) sp)->fd, &rfds);
FD_SET (UART_DATA(sp)->fd, &rfds);
if (iAbortFd) {
FD_SET (iAbortFd, &rfds);
}
/*
* Some implementations (e.g. Linux) of select(2) will update *timeout.
* Make a copy so that it will be updated on these systems,
*/
struct timeval fixed_timeout;
if (timeout) {
fixed_timeout = *timeout;
timeout = &fixed_timeout;
struct timeval timeout_tv;
if (timeout > 0) {
timeout_tv.tv_sec = (timeout / 1000);
timeout_tv.tv_usec = ((timeout % 1000) * 1000);
}
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)) {
// The system call was interupted by a signal and a signal handler was
@ -287,38 +283,38 @@ select:
// Read error
if (res < 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%s", "RX error.");
return ECOMIO;
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Error: %s", strerror(errno));
return NFC_EIO;
}
// Read time-out
if (res == 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Timeout!");
return ECOMTIMEOUT;
return NFC_ETIMEOUT;
}
if (FD_ISSET (iAbortFd, &rfds)) {
// Abort requested
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Abort!");
close (iAbortFd);
return EOPABORT;
return NFC_EOPABORTED;
}
// 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) {
return ECOMIO;
return NFC_EIO;
}
// 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
if (res <= 0) {
return ECOMIO;
return NFC_EIO;
}
received_bytes_count += res;
} while (expected_bytes_count > received_bytes_count);
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
*/
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;
LOG_HEX ("TX", pbtTx, szTx);
if ((int) szTx == write (((serial_port_unix *) sp)->fd, pbtTx, szTx))
return 0;
if ((int) szTx == write (UART_DATA(sp)->fd, pbtTx, szTx))
return NFC_SUCCESS;
else
return ECOMIO;
return NFC_EIO;
}
char **

View file

@ -31,17 +31,17 @@
#include "contrib/windows.h"
#define delay_ms( X ) Sleep( X )
typedef struct {
struct serial_port_windows {
HANDLE hPort; // Serial port handle
DCB dcb; // Device control settings
COMMTIMEOUTS ct; // Serial port time-out configuration
} serial_port_windows;
};
serial_port
uart_open (const char *pcPortName)
{
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
sprintf (acPortName, "\\\\.\\%s", pcPortName);
@ -85,8 +85,8 @@ uart_open (const char *pcPortName)
void
uart_close (const serial_port sp)
{
if (((serial_port_windows *) sp)->hPort != INVALID_HANDLE_VALUE) {
CloseHandle (((serial_port_windows *) sp)->hPort);
if (((struct serial_port_windows *) sp)->hPort != INVALID_HANDLE_VALUE) {
CloseHandle (((struct serial_port_windows *) sp)->hPort);
}
free (sp);
}
@ -94,13 +94,13 @@ uart_close (const serial_port sp)
void
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
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);
// 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);
return;
};
spw = (serial_port_windows *) sp;
spw = (struct serial_port_windows *) sp;
// Set baud rate
spw->dcb.BaudRate = uiPortSpeed;
@ -131,7 +131,7 @@ uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
uint32_t
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))
return spw->dcb.BaudRate;
@ -139,7 +139,7 @@ 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)
uart_receive (serial_port sp, uint8_t * pbtRx, const size_t szRx, void * abort_p, int timeout)
{
DWORD dwBytesToGet = (DWORD)szRx;
DWORD dwBytesReceived = 0;
@ -147,7 +147,7 @@ uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx, void * abort_p,
BOOL res;
// 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;
timeouts.ReadIntervalTimeout = 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.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.");
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;
do {
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,
&dwBytesReceived, NULL);
@ -194,24 +194,24 @@ uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx, void * abort_p,
}
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;
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = timeout ? ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000)) : 0;
timeouts.ReadTotalTimeoutConstant = timeout;
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.");
return ECOMIO;
}
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;
}
if (!dwTxLen)
@ -238,7 +238,7 @@ BOOL is_port_available(int nPort)
char **
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 i;
for (i = 1; i <= MAX_SERIAL_PORT_WIN; i++) {

View file

@ -7,9 +7,3 @@ noinst_LTLIBRARIES = libnfcchips.la
libnfcchips_la_SOURCES = pn53x.c
libnfcchips_la_CFLAGS = -I$(top_srcdir)/libnfc
if HAS_LOG4C
libnfcchips_la_CFLAGS += @log4c_CFLAGS@
libnfcchips_la_LIBADD = @log4c_LIBS@
endif

View file

@ -115,7 +115,7 @@ typedef struct {
uint8_t ui8Code;
uint8_t ui8CompatFlags;
#ifdef LOGGING
const char * abtCommandText;
const char *abtCommandText;
#endif
} pn53x_command;
@ -203,8 +203,8 @@ static const pn53x_command pn53x_commands[] = {
#ifdef LOGGING
typedef struct {
uint16_t ui16Address;
const char * abtRegisterText;
const char * abtRegisterDescription;
const char *abtRegisterText;
const char *abtRegisterDescription;
} pn53x_register;
# define PNREG( X, Y ) { X , #X, Y }
@ -299,6 +299,34 @@ typedef struct {
#define PN53X_SFR_P7CFGB 0xFFF5
#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
static const pn53x_register pn53x_registers[] = {

File diff suppressed because it is too large Load diff

View file

@ -127,8 +127,8 @@ typedef enum {
} pn53x_operating_mode;
struct pn53x_io {
bool (*send)(nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout);
int (*receive)(nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen, struct timeval *timeout);
int (*send)(struct nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout);
int (*receive)(struct nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, int timeout);
};
/* defines */
@ -143,15 +143,17 @@ struct pn53x_data {
/** Current operating mode */
pn53x_operating_mode operating_mode;
/** Current emulated target */
nfc_target_t* current_target;
nfc_target *current_target;
/** 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 */
uint8_t ui8TxBits;
/** Register cache for SetParameters function. */
uint8_t ui8Parameters;
/** Last sent command */
uint8_t ui8LastCommand;
uint8_t last_command;
/** Interframe timer correction */
int16_t timer_correction;
/** Timer prescaler */
@ -160,12 +162,18 @@ struct pn53x_data {
uint8_t wb_data[PN53X_CACHE_REGISTER_SIZE];
uint8_t wb_mask[PN53X_CACHE_REGISTER_SIZE];
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))
/**
* @enum pn53x_modulation_t
* @enum pn53x_modulation
* @brief NFC modulation
*/
typedef enum {
@ -187,10 +195,10 @@ typedef enum {
PM_ISO14443B_424 = 0x07,
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 (Not supported by PN531 nor PN532) */
PM_ISO14443B_847 = 0x08,
} pn53x_modulation_t;
} pn53x_modulation;
/**
* @enum pn53x_target_type_t
* @enum pn53x_target_type
* @brief NFC target type enumeration
*/
typedef enum {
@ -228,7 +236,7 @@ typedef enum {
PTT_DEP_ACTIVE_212 = 0x81,
/** DEP active 424 kbps */
PTT_DEP_ACTIVE_424 = 0x82,
} pn53x_target_type_t;
} pn53x_target_type;
typedef enum {
PSM_NORMAL = 0x01,
@ -238,7 +246,7 @@ typedef enum {
} pn532_sam_mode;
/**
* @enum pn53x_target_mode_t
* @enum pn53x_target_mode
* @brief PN53x target mode enumeration
*/
typedef enum {
@ -250,104 +258,104 @@ typedef enum {
PTM_DEP_ONLY = 0x02,
/** Configure the PN532 to accept to be initialized only as ISO/IEC14443-4 PICC */
PTM_ISO14443_4_PICC_ONLY = 0x04
} pn53x_target_mode_t;
} pn53x_target_mode;
extern const byte_t pn53x_ack_frame[6];
extern const byte_t pn53x_nack_frame[6];
extern const uint8_t pn53x_ack_frame[6];
extern const uint8_t pn53x_nack_frame[6];
bool pn53x_init(nfc_device_t * 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_init(struct nfc_device *pnd);
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);
bool pn53x_set_tx_bits (nfc_device_t * pnd, const uint8_t ui8Bits);
bool pn53x_wrap_frame (const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, byte_t * pbtFrame,
size_t * pszFrameBits);
bool pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t * pbtRx, size_t * pszRxBits,
byte_t * pbtRxPar);
bool pn53x_decode_target_data (const byte_t * pbtRawData, size_t szRawData,
pn53x_type chip_type, nfc_modulation_type_t nmt,
nfc_target_info_t * pnti);
bool pn53x_read_register (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t * ui8Value);
bool pn53x_write_register (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t ui8SymbolMask, uint8_t ui8Value);
bool pn53x_get_firmware_version (nfc_device_t * pnd, char abtFirmwareText[22]);
bool pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
bool pn53x_check_communication (nfc_device_t *pnd);
bool pn53x_idle (nfc_device_t * pnd);
int pn53x_set_parameters (struct nfc_device *pnd, const uint8_t ui8Value, const bool bEnable);
int pn53x_set_tx_bits (struct nfc_device *pnd, const uint8_t ui8Bits);
int pn53x_wrap_frame (const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtFrame);
int pn53x_unwrap_frame (const uint8_t *pbtFrame, const size_t szFrameBits, uint8_t *pbtRx, uint8_t *pbtRxPar);
int pn53x_decode_target_data (const uint8_t *pbtRawData, size_t szRawData,
pn53x_type chip_type, nfc_modulation_type nmt,
nfc_target_info *pnti);
int pn53x_read_register (struct nfc_device *pnd, uint16_t ui16Reg, uint8_t *ui8Value);
int pn53x_write_register (struct nfc_device *pnd, uint16_t ui16Reg, uint8_t ui8SymbolMask, uint8_t ui8Value);
int pn53x_get_firmware_version (struct nfc_device *pnd, char abtFirmwareText[22]);
int pn53x_set_property_int (struct nfc_device *pnd, const nfc_property property, const int value);
int pn53x_set_property_bool (struct nfc_device *pnd, const nfc_property property, const bool bEnable);
int pn53x_check_communication (struct nfc_device *pnd);
int pn53x_idle (struct nfc_device *pnd);
// NFC device as Initiator functions
bool pn53x_initiator_init (nfc_device_t * pnd);
bool pn53x_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);
bool pn53x_initiator_poll_target (nfc_device_t * pnd,
const nfc_modulation_t * pnmModulations, const size_t szModulations,
int pn53x_initiator_init (struct nfc_device *pnd);
int pn53x_initiator_select_passive_target (struct nfc_device *pnd,
const nfc_modulation nm,
const uint8_t *pbtInitData, const size_t szInitData,
nfc_target *pnt);
int pn53x_initiator_poll_target (struct nfc_device *pnd,
const nfc_modulation *pnmModulations, const size_t szModulations,
const uint8_t uiPollNr, const uint8_t uiPeriod,
nfc_target_t * pnt);
bool pn53x_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);
bool pn53x_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);
bool pn53x_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx,
byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
bool pn53x_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);
bool pn53x_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);
bool pn53x_initiator_deselect_target (nfc_device_t * pnd);
nfc_target *pnt);
int pn53x_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);
int pn53x_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);
int pn53x_initiator_transceive_bytes (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx,
uint8_t *pbtRx, size_t *pszRx, int timeout);
int pn53x_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);
int pn53x_initiator_transceive_bytes_timed (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx,
uint8_t *pbtRx, uint32_t *cycles);
int pn53x_initiator_deselect_target (struct nfc_device *pnd);
// NFC device as Target functions
bool pn53x_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx);
bool pn53x_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
bool pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
bool pn53x_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_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_init (struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRxLen, int timeout);
int pn53x_target_receive_bits (struct nfc_device *pnd, uint8_t *pbtRx, const size_t szRxLen, uint8_t *pbtRxPar);
int pn53x_target_receive_bytes (struct nfc_device *pnd, uint8_t *pbtRx, const size_t szRxLen, int timeout);
int pn53x_target_send_bits (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar);
int pn53x_target_send_bytes (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int timeout);
// 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
bool pn53x_SetParameters (nfc_device_t * pnd, const uint8_t ui8Value);
bool pn53x_SAMConfiguration (nfc_device_t * pnd, const pn532_sam_mode mode, struct timeval *timeout);
bool pn53x_PowerDown (nfc_device_t * pnd);
bool pn53x_InListPassiveTarget (nfc_device_t * pnd, const pn53x_modulation_t pmInitModulation,
const byte_t szMaxTargets, const byte_t * pbtInitiatorData,
const size_t szInitiatorDataLen, byte_t * pbtTargetsData, size_t * pszTargetsData,
struct timeval *timeout);
bool pn53x_InDeselect (nfc_device_t * pnd, const uint8_t ui8Target);
bool pn53x_InRelease (nfc_device_t * pnd, const uint8_t ui8Target);
bool pn53x_InAutoPoll (nfc_device_t * pnd, const pn53x_target_type_t * ppttTargetTypes, const size_t szTargetTypes,
const byte_t btPollNr, const byte_t btPeriod, nfc_target_t * pntTargets,
size_t * pszTargetFound);
bool pn53x_InJumpForDEP (nfc_device_t * pnd,
const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr,
const byte_t * pbtPassiveInitiatorData,
const byte_t * pbtNFCID3i,
const byte_t * pbtGB, const size_t szGB,
nfc_target_t * pnt);
bool pn53x_TgInitAsTarget (nfc_device_t * pnd, pn53x_target_mode_t ptm,
const byte_t * pbtMifareParams,
const byte_t * pbtTkt, size_t szTkt,
const byte_t * pbtFeliCaParams,
const byte_t * pbtNFCID3t, const byte_t * pbtGB, const size_t szGB,
byte_t * pbtRx, size_t * pszRx, byte_t * pbtModeByte);
int pn53x_SetParameters (struct nfc_device *pnd, const uint8_t ui8Value);
int pn53x_SAMConfiguration (struct nfc_device *pnd, const pn532_sam_mode mode, int timeout);
int pn53x_PowerDown (struct nfc_device *pnd);
int pn53x_InListPassiveTarget (struct nfc_device *pnd, const pn53x_modulation pmInitModulation,
const uint8_t szMaxTargets, const uint8_t *pbtInitiatorData,
const size_t szInitiatorDataLen, uint8_t *pbtTargetsData, size_t *pszTargetsData,
int timeout);
int pn53x_InDeselect (struct nfc_device *pnd, const uint8_t ui8Target);
int pn53x_InRelease (struct nfc_device *pnd, const uint8_t ui8Target);
int pn53x_InAutoPoll (struct nfc_device *pnd, const pn53x_target_type *ppttTargetTypes, const size_t szTargetTypes,
const uint8_t btPollNr, const uint8_t btPeriod, nfc_target *pntTargets,
const int timeout);
int pn53x_InJumpForDEP (struct nfc_device *pnd,
const nfc_dep_mode ndm, const nfc_baud_rate nbr,
const uint8_t *pbtPassiveInitiatorData,
const uint8_t *pbtNFCID3i,
const uint8_t *pbtGB, const size_t szGB,
nfc_target *pnt,
const int timeout);
int pn53x_TgInitAsTarget (struct nfc_device *pnd, pn53x_target_mode ptm,
const uint8_t *pbtMifareParams,
const uint8_t *pbtTkt, size_t szTkt,
const uint8_t *pbtFeliCaParams,
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
bool pn53x_RFConfiguration__RF_field (nfc_device_t * pnd, bool bEnable);
bool pn53x_RFConfiguration__Various_timings (nfc_device_t * pnd, const uint8_t fATR_RES_Timeout, const uint8_t fRetryTimeout);
bool pn53x_RFConfiguration__MaxRtyCOM (nfc_device_t * 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__RF_field (struct nfc_device *pnd, bool bEnable);
int pn53x_RFConfiguration__Various_timings (struct nfc_device *pnd, const uint8_t fATR_RES_Timeout, const uint8_t fRetryTimeout);
int pn53x_RFConfiguration__MaxRtyCOM (struct nfc_device *pnd, const uint8_t MaxRtyCOM);
int pn53x_RFConfiguration__MaxRetries (struct nfc_device *pnd, const uint8_t MxRtyATR, const uint8_t MxRtyPSL, const uint8_t MxRtyPassiveActivation);
// Misc
bool pn53x_check_ack_frame (nfc_device_t * pnd, const byte_t * pbtRxFrame, const size_t szRxFrameLen);
bool pn53x_check_error_frame (nfc_device_t * pnd, const byte_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_check_ack_frame (struct nfc_device *pnd, const uint8_t *pbtRxFrame, const size_t szRxFrameLen);
int pn53x_check_error_frame (struct nfc_device *pnd, const uint8_t *pbtRxFrame, const size_t szRxFrameLen);
int pn53x_build_frame (uint8_t *pbtFrame, size_t *pszFrame, const uint8_t *pbtData, const size_t szData);
void pn53x_data_new (nfc_device_t * pnd, const struct pn53x_io* io);
void pn53x_data_free (nfc_device_t * pnd);
void pn53x_data_new (struct nfc_device *pnd, const struct pn53x_io *io);
void pn53x_data_free (struct nfc_device *pnd);
#endif // __NFC_CHIPS_PN53X_H__

View file

@ -50,6 +50,6 @@
# define DRIVERS_MAX_DEVICES 16
extern const struct nfc_driver_t *nfc_drivers[];
extern const struct nfc_driver *nfc_drivers[];
#endif // __NFC_DRIVERS_H__

View file

@ -38,8 +38,3 @@ if LIBUSB_ENABLED
libnfcdrivers_la_LIBADD += @libusb_LIBS@
endif
if HAS_LOG4C
libnfcdrivers_la_CFLAGS += @log4c_CFLAGS@
libnfcdrivers_la_LIBADD += @log4c_LIBS@
endif

View file

@ -26,6 +26,7 @@
# include "config.h"
#endif // HAVE_CONFIG_H
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@ -40,7 +41,7 @@
// Bus
#include <winscard.h>
# define ACR122_DRIVER_NAME "ACR122"
#define ACR122_DRIVER_NAME "acr122"
#if defined (_WIN32)
# define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE SCARD_CTL_CODE(3500)
@ -76,7 +77,7 @@
const struct pn53x_io acr122_io;
char *acr122_firmware (nfc_device_t *pnd);
char *acr122_firmware (nfc_device *pnd);
const char *supported_devices[] = {
"ACS ACR122", // ACR122U & Touchatag, last version
@ -89,7 +90,7 @@ const char *supported_devices[] = {
struct acr122_data {
SCARDHANDLE hCard;
SCARD_IO_REQUEST ioCard;
byte_t abtRx[ACR122_RESPONSE_LEN];
uint8_t abtRx[ACR122_RESPONSE_LEN];
size_t szRx;
};
@ -123,7 +124,7 @@ acr122_free_scardcontext (void)
#define PCSC_MAX_DEVICES 16
/**
* @brief List connected devices
* @brief List opened devices
*
* Probe PCSC to find NFC capable hardware.
*
@ -133,7 +134,7 @@ acr122_free_scardcontext (void)
* @return true if succeeded, false otherwise.
*/
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;
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)
return false;
// DBG("%s", "PCSC reports following device(s):");
while ((acDeviceNames[szPos] != '\0') && ((*pszDeviceFound) < szDevices)) {
while ((acDeviceNames[szPos] != '\0') && ((*pszDeviceFound) < connstrings_len)) {
uiBusIndex++;
// 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) {
// Supported ACR122 device found
strncpy (pnddDevices[*pszDeviceFound].acDevice, acDeviceNames + szPos, DEVICE_NAME_LENGTH - 1);
pnddDevices[*pszDeviceFound].pcDriver = ACR122_DRIVER_NAME;
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
snprintf (connstrings[*pszDeviceFound], sizeof(nfc_connstring), "%s:%s:%"PRIu32, ACR122_DRIVER_NAME, acDeviceNames + szPos, uiBusIndex);
(*pszDeviceFound)++;
} else {
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;
}
nfc_device_t *
acr122_connect (const nfc_device_desc_t * pndd)
struct acr122_descriptor {
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;
nfc_device_t *pnd = nfc_device_new ();
nfc_device *pnd = nfc_device_new (connstring);
pnd->driver_data = malloc (sizeof (struct acr122_data));
// Alloc and init chip's data
pn53x_data_new (pnd, &acr122_io);
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
if (!(pscc = acr122_get_scardcontext ()))
goto error;
// 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
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.
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%s", "PCSC connect failed");
goto error;
@ -222,7 +281,7 @@ acr122_connect (const nfc_device_desc_t * pndd)
if (strstr (pcFirmware, FIRMWARE_TEXT) != NULL) {
// 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
// 46: empirical tuning on ACR122U
@ -242,7 +301,7 @@ error:
}
void
acr122_disconnect (nfc_device_t * pnd)
acr122_close (nfc_device *pnd)
{
SCardDisconnect (DRIVER_DATA (pnd)->hCard, SCARD_LEAVE_CARD);
acr122_free_scardcontext ();
@ -251,21 +310,21 @@ acr122_disconnect (nfc_device_t * pnd)
nfc_device_free (pnd);
}
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)
{
// FIXME: timeout is not handled
(void) timeout;
// Make sure the command does not overflow the send buffer
if (szData > ACR122_COMMAND_LEN) {
pnd->iLastError = EINVALARG;
return false;
pnd->last_error = NFC_EINVARG;
return pnd->last_error;
}
// Prepare and transmit the send buffer
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);
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.
*/
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;
return false;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
} 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.
*/
if (SCardTransmit (DRIVER_DATA (pnd)->hCard, &(DRIVER_DATA (pnd)->ioCard), abtTxBuf, szTxBuf, NULL, DRIVER_DATA (pnd)->abtRx, &dwRxLen) != SCARD_S_SUCCESS) {
pnd->iLastError = ECOMIO;
return false;
pnd->last_error = NFC_EIO;
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
if (dwRxLen != 2) {
pnd->iLastError = ECOMIO;
return false;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
// Check if the operation was successful, so an answer is available
if (DRIVER_DATA (pnd)->abtRx[0] == SCARD_OPERATION_ERROR) {
pnd->iLastError = EFRAISERRFRAME;
return false;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
} else {
DRIVER_DATA (pnd)->szRx = dwRxLen;
}
return true;
return NFC_SUCCESS;
}
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
(void) timeout;
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) {
/*
@ -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);
abtRxCmd[4] = DRIVER_DATA (pnd)->abtRx[1];
if (SCardTransmit (DRIVER_DATA (pnd)->hCard, &(DRIVER_DATA (pnd)->ioCard), abtRxCmd, sizeof (abtRxCmd), NULL, DRIVER_DATA (pnd)->abtRx, &dwRxLen) != SCARD_S_SUCCESS) {
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
DRIVER_DATA (pnd)->szRx = dwRxLen;
} 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
if (DRIVER_DATA (pnd)->szRx < 4 || (DRIVER_DATA (pnd)->szRx - 4) > szData) {
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
// Wipe out the 4 APDU emulation bytes: D5 4B .. .. .. 90 00
len = DRIVER_DATA (pnd)->szRx - 4;
memcpy (pbtData, DRIVER_DATA (pnd)->abtRx + 2, len);
// Transmission went successful
pnd->iLastError = 0;
return len;
}
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;
static char abtFw[11];
DWORD dwFwLen = sizeof (abtFw);
memset (abtFw, 0x00, sizeof (abtFw));
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 {
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) {
@ -387,10 +444,10 @@ acr122_firmware (nfc_device_t *pnd)
#if 0
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 };
byte_t abtBuf[2];
uint8_t abtLed[9] = { 0xFF, 0x00, 0x40, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00 };
uint8_t abtBuf[2];
DWORD dwBufLen = sizeof (abtBuf);
(void) bOn;
if (DRIVER_DATA (pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
@ -406,12 +463,12 @@ const struct pn53x_io acr122_io = {
.receive = acr122_receive,
};
const struct nfc_driver_t acr122_driver = {
.name = ACR122_DRIVER_NAME,
.probe = acr122_probe,
.connect = acr122_connect,
.disconnect = acr122_disconnect,
.strerror = pn53x_strerror,
const struct nfc_driver acr122_driver = {
.name = ACR122_DRIVER_NAME,
.probe = acr122_probe,
.open = acr122_open,
.close = acr122_close,
.strerror = pn53x_strerror,
.initiator_init = pn53x_initiator_init,
.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_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,
.idle = NULL,
.abort_command = NULL, // FIXME: abort is not supported in this driver
.idle = NULL, // FIXME: idle is not supported in this driver
};

View file

@ -26,14 +26,14 @@
# 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
nfc_device_t *acr122_connect (const nfc_device_desc_t * pndd);
bool acr122_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout);
int acr122_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struct timeval *timeout);
void acr122_disconnect (nfc_device_t * pnd);
nfc_device *acr122_open (const nfc_connstring connstring);
int acr122_send (nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout);
int acr122_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szData, int timeout);
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__

View file

@ -29,6 +29,9 @@
#include "acr122s.h"
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <sys/param.h>
#include <string.h>
#include <unistd.h>
@ -46,7 +49,7 @@
struct acr122s_data {
serial_port port;
byte_t seq;
uint8_t seq;
#ifndef WIN32
int abort_fds[2];
#else
@ -84,74 +87,74 @@ enum {
#pragma pack(push, 1)
struct icc_power_on_req {
byte_t message_type;
uint8_t message_type;
uint32_t length;
byte_t slot;
byte_t seq;
byte_t power_select;
byte_t rfu[2];
uint8_t slot;
uint8_t seq;
uint8_t power_select;
uint8_t rfu[2];
};
struct icc_power_on_res {
byte_t message_type;
uint8_t message_type;
uint32_t length;
byte_t slot;
byte_t seq;
byte_t status;
byte_t error;
byte_t chain_parameter;
uint8_t slot;
uint8_t seq;
uint8_t status;
uint8_t error;
uint8_t chain_parameter;
};
struct icc_power_off_req {
byte_t message_type;
uint8_t message_type;
uint32_t length;
byte_t slot;
byte_t seq;
byte_t rfu[3];
uint8_t slot;
uint8_t seq;
uint8_t rfu[3];
};
struct icc_power_off_res {
byte_t message_type;
uint8_t message_type;
uint32_t length;
byte_t slot;
byte_t seq;
byte_t status;
byte_t error;
byte_t clock_status;
uint8_t slot;
uint8_t seq;
uint8_t status;
uint8_t error;
uint8_t clock_status;
};
struct xfr_block_req {
byte_t message_type;
uint8_t message_type;
uint32_t length;
byte_t slot;
byte_t seq;
byte_t bwi;
byte_t rfu[2];
uint8_t slot;
uint8_t seq;
uint8_t bwi;
uint8_t rfu[2];
};
struct xfr_block_res {
byte_t message_type;
uint8_t message_type;
uint32_t length;
byte_t slot;
byte_t seq;
byte_t status;
byte_t error;
byte_t chain_parameter;
uint8_t slot;
uint8_t seq;
uint8_t status;
uint8_t error;
uint8_t chain_parameter;
};
struct apdu_header {
byte_t class;
byte_t ins;
byte_t p1;
byte_t p2;
byte_t length;
uint8_t class;
uint8_t ins;
uint8_t p1;
uint8_t p2;
uint8_t length;
};
#pragma pack(pop)
#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.
@ -162,7 +165,7 @@ struct apdu_header {
*/
#if 0
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);
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
*/
static void
acr122s_fix_frame(byte_t *frame)
acr122s_fix_frame(uint8_t *frame)
{
size_t frame_size = FRAME_SIZE(frame);
frame[0] = STX;
frame[frame_size - 1] = ETX;
byte_t *csum = frame + frame_size - 2;
uint8_t *csum = frame + frame_size - 2;
*csum = 0;
for (byte_t *p = frame + 1; p < csum; p++)
for (uint8_t *p = frame + 1; p < csum; p++)
*csum ^= *p;
}
/**
* 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: timeout
* @return 0 if success
*/
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);
byte_t ack[4];
byte_t positive_ack[4] = { STX, 0, 0, ETX };
serial_port port = DRIVER_DATA(dev)->port;
uint8_t ack[4];
uint8_t positive_ack[4] = { STX, 0, 0, ETX };
serial_port port = DRIVER_DATA(pnd)->port;
int ret;
void *abort_p;
#ifndef WIN32
abort_p = &(DRIVER_DATA(dev)->abort_fds[1]);
abort_p = &(DRIVER_DATA(pnd)->abort_fds[1]);
#else
abort_p = &(DRIVER_DATA(dev)->abort_flag);
abort_p = &(DRIVER_DATA(pnd)->abort_flag);
#endif
if ((ret = uart_send(port, frame, frame_size, timeout)) != 0)
if ((ret = uart_send(port, frame, frame_size, timeout)) < 0)
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;
if (memcmp(ack, positive_ack, 4) != 0)
return ECOMIO;
if (memcmp(ack, positive_ack, 4) != 0){
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
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;
}
@ -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().
*
* @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_size is frame size
* @param: abort_p
@ -243,29 +248,33 @@ acr122s_send_frame(nfc_device_t *dev, byte_t *frame, struct timeval *timeout)
* @return 0 if success
*/
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)
return EINVALARG;
pnd->last_error = NFC_EINVARG;
return pnd->last_error;
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)
return ret;
// Is buffer sufficient to store response?
if (frame_size < FRAME_SIZE(frame))
return ECOMIO;
if (frame_size < FRAME_SIZE(frame)){
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
size_t remaining = FRAME_SIZE(frame) - 11;
if ((ret = uart_receive(port, frame + 11, remaining, abort_p, timeout)) != 0)
return ret;
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.");
return ECOMIO;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
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
le32(uint32_t val) {
uint32_t res;
byte_t *p = (byte_t *) &res;
uint8_t *p = (uint8_t *) &res;
p[0] = val;
p[1] = val >> 8;
p[2] = val >> 16;
@ -290,7 +299,7 @@ le32(uint32_t val) {
/**
* 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_size is the passed command frame size
* @param p1
@ -302,9 +311,9 @@ le32(uint32_t val) {
* @return true if frame built successfully
*/
static bool
acr122s_build_frame(nfc_device_t *dev,
byte_t *frame, size_t frame_size, byte_t p1, byte_t p2,
const byte_t *data, size_t data_size, int should_prefix)
acr122s_build_frame(nfc_device *pnd,
uint8_t *frame, size_t frame_size, uint8_t p1, uint8_t p2,
const uint8_t *data, size_t data_size, int should_prefix)
{
if (frame_size < data_size + APDU_OVERHEAD + should_prefix)
return false;
@ -315,7 +324,7 @@ acr122s_build_frame(nfc_device_t *dev,
req->message_type = XFR_BLOCK_REQ_MSG;
req->length = le32(5 + data_size + should_prefix);
req->slot = 0;
req->seq = DRIVER_DATA(dev)->seq;
req->seq = DRIVER_DATA(pnd)->seq;
req->bwi = 0;
req->rfu[0] = 0;
req->rfu[1] = 0;
@ -327,7 +336,7 @@ acr122s_build_frame(nfc_device_t *dev,
header->p2 = p2;
header->length = data_size + should_prefix;
byte_t *buf = (byte_t *) &frame[16];
uint8_t *buf = (uint8_t *) &frame[16];
if (should_prefix)
*buf++ = 0xD4;
memcpy(buf, data, data_size);
@ -337,61 +346,61 @@ acr122s_build_frame(nfc_device_t *dev,
}
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));
cmd[1] = ICC_POWER_ON_REQ_MSG;
acr122s_fix_frame(cmd);
byte_t resp[MAX_FRAME_SIZE];
uint8_t resp[MAX_FRAME_SIZE];
int ret;
if ((ret = acr122s_send_frame(dev, cmd, 0)) != 0)
if ((ret = acr122s_send_frame(pnd, cmd, 0)) != 0)
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;
CHIP_DATA(dev)->power_mode = NORMAL;
CHIP_DATA(pnd)->power_mode = NORMAL;
return 0;
}
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));
cmd[1] = ICC_POWER_OFF_REQ_MSG;
acr122s_fix_frame(cmd);
byte_t resp[MAX_FRAME_SIZE];
uint8_t resp[MAX_FRAME_SIZE];
int ret;
if ((ret = acr122s_send_frame(dev, cmd, 0)) != 0)
if ((ret = acr122s_send_frame(pnd, cmd, 0)) != 0)
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;
CHIP_DATA(dev)->power_mode = LOWVBAT;
CHIP_DATA(pnd)->power_mode = LOWVBAT;
return 0;
}
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;
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;
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;
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;
}
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
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
* sending some commands. But using this way to probe devices, we can
* have serious problem with other device on this bus */
#ifndef SERIAL_AUTOPROBE_ENABLED
(void) descs;
(void) desc_count;
*dev_found = 0;
(void) connstrings;
(void) connstrings_len;
*pszDeviceFound = 0;
log_put(LOG_CATEGORY, NFC_PRIORITY_INFO, "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
return false;
#else /* SERIAL_AUTOPROBE_ENABLED */
*dev_found = 0;
char **ports = uart_list_ports();
for (int i = 0; ports[i]; i++) {
char *port = ports[i];
serial_port sp = uart_open(port);
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Trying to find ACR122S device on serial port: %s at %d bauds.", port, ACR122S_DEFAULT_SPEED);
*pszDeviceFound = 0;
serial_port sp;
char **acPorts = uart_list_ports ();
const char *acPort;
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)) {
uart_flush_input(sp);
uart_set_speed(sp, ACR122S_DEFAULT_SPEED);
// We need to flush input to be sure first reply does not comes from older byte transceive
uart_flush_input (sp);
uart_set_speed (sp, ACR122S_DEFAULT_SPEED);
nfc_device_t *dev = nfc_device_new();
dev->driver = &acr122s_driver;
nfc_connstring connstring;
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));
DRIVER_DATA(dev)->port = sp;
DRIVER_DATA(dev)->seq = 0;
pnd->driver = &acr122s_driver;
pnd->driver_data = malloc(sizeof(struct acr122s_data));
DRIVER_DATA (pnd)->port = sp;
DRIVER_DATA(pnd)->seq = 0;
#ifndef WIN32
pipe(DRIVER_DATA(dev)->abort_fds);
pipe(DRIVER_DATA(pnd)->abort_fds);
#else
DRIVER_DATA(dev)->abort_flag = false;
DRIVER_DATA(pnd)->abort_flag = false;
#endif
pn53x_data_new(dev, &acr122s_io);
CHIP_DATA(dev)->type = PN532;
CHIP_DATA(dev)->power_mode = NORMAL;
pn53x_data_new(pnd, &acr122s_io);
CHIP_DATA(pnd)->type = PN532;
CHIP_DATA(pnd)->power_mode = NORMAL;
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) {
ret = -1;
}
pn53x_data_free(dev);
nfc_device_free(dev);
pn53x_data_free(pnd);
nfc_device_free(pnd);
uart_close(sp);
if (ret != 0)
continue;
nfc_device_desc_t *desc = &descs[(*dev_found)++];
snprintf(desc->acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", ACR122S_DRIVER_NAME, port);
desc->pcDriver = ACR122S_DRIVER_NAME;
strncpy(desc->acPort, port, DEVICE_PORT_LENGTH - 1);
desc->acPort[DEVICE_PORT_LENGTH - 1] = '\0';
desc->uiSpeed = ACR122S_DEFAULT_SPEED;
// ACR122S reader is found
memcpy (connstrings[*pszDeviceFound], connstring, sizeof(nfc_connstring));
(*pszDeviceFound)++;
// Test if we reach the maximum "wanted" devices
if (*dev_found >= desc_count)
if (*pszDeviceFound >= connstrings_len)
break;
}
}
for (int i = 0; ports[i]; i++)
free(ports[i]);
free(ports);
return true;
iDevice = 0;
while ((acPort = acPorts[iDevice++])) {
free ((void*)acPort);
}
free (acPorts);
#endif /* SERIAL_AUTOPROBE_ENABLED */
return true;
}
nfc_device_t *
acr122s_connect(const nfc_device_desc_t *desc)
nfc_device *
acr122s_open(const nfc_connstring connstring)
{
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,
"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) {
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR,
"Invalid serial port: %s", desc->acPort);
"Invalid serial port: %s", ndd.port);
return NULL;
}
if (sp == CLAIMED_SERIAL_PORT) {
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR,
"Serial port already claimed: %s", desc->acPort);
"Serial port already claimed: %s", ndd.port);
return NULL;
}
uart_flush_input(sp);
uart_set_speed(sp, desc->uiSpeed);
uart_set_speed(sp, ndd.speed);
dev = nfc_device_new();
dev->driver = &acr122s_driver;
strcpy(dev->acName, ACR122S_DRIVER_NAME);
pnd = nfc_device_new(connstring);
pnd->driver = &acr122s_driver;
strcpy(pnd->name, ACR122S_DRIVER_NAME);
dev->driver_data = malloc(sizeof(struct acr122s_data));
DRIVER_DATA(dev)->port = sp;
DRIVER_DATA(dev)->seq = 0;
pnd->driver_data = malloc(sizeof(struct acr122s_data));
DRIVER_DATA(pnd)->port = sp;
DRIVER_DATA(pnd)->seq = 0;
#ifndef WIN32
pipe(DRIVER_DATA(dev)->abort_fds);
pipe(DRIVER_DATA(pnd)->abort_fds);
#else
DRIVER_DATA(dev)->abort_flag = false;
DRIVER_DATA(pnd)->abort_flag = false;
#endif
pn53x_data_new(dev, &acr122s_io);
CHIP_DATA(dev)->type = PN532;
pn53x_data_new(pnd, &acr122s_io);
CHIP_DATA(pnd)->type = PN532;
#if 1
// Retrieve firmware version
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.");
acr122s_disconnect(dev);
acr122s_close(pnd);
return NULL;
}
if (strncmp(version, "ACR122S", 7) != 0) {
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "Invalid firmware version: %s",
version);
acr122s_disconnect(dev);
acr122s_close(pnd);
return NULL;
}
snprintf(dev->acName, sizeof(dev->acName), "%s", version);
snprintf(pnd->name, sizeof(pnd->name), "%s", version);
// 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.");
acr122s_disconnect(dev);
acr122s_close(pnd);
return NULL;
}
#endif
if (!pn53x_init(dev)) {
if (!pn53x_init(pnd)) {
log_put(LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Failed initializing PN532 chip.");
acr122s_disconnect(dev);
acr122s_close(pnd);
return NULL;
}
return dev;
return pnd;
}
void
acr122s_disconnect (nfc_device_t *dev)
acr122s_close (nfc_device *pnd)
{
acr122s_deactivate_sam(dev);
uart_close(DRIVER_DATA(dev)->port);
acr122s_deactivate_sam(pnd);
uart_close(DRIVER_DATA(pnd)->port);
#ifndef WIN32
// Release file descriptors used for abort mecanism
close (DRIVER_DATA(dev)->abort_fds[0]);
close (DRIVER_DATA(dev)->abort_fds[1]);
close (DRIVER_DATA(pnd)->abort_fds[0]);
close (DRIVER_DATA(pnd)->abort_fds[1]);
#endif
pn53x_data_free(dev);
nfc_device_free(dev);
}
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;
pn53x_data_free(pnd);
nfc_device_free(pnd);
}
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;
#ifndef WIN32
abort_p = &(DRIVER_DATA(dev)->abort_fds[1]);
abort_p = &(DRIVER_DATA(pnd)->abort_fds[1]);
#else
abort_p = &(DRIVER_DATA(dev)->abort_flag);
abort_p = &(DRIVER_DATA(pnd)->abort_flag);
#endif
byte_t tmp[MAX_FRAME_SIZE];
dev->iLastError = acr122s_recv_frame(dev, tmp, sizeof(tmp), abort_p, timeout);
uint8_t tmp[MAX_FRAME_SIZE];
pnd->last_error = acr122s_recv_frame(pnd, tmp, sizeof(tmp), abort_p, timeout);
if (abort_p && (EOPABORT == dev->iLastError))
return -1;
if (abort_p && (NFC_EOPABORTED == pnd->last_error)) {
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)");
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;
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);
dev->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
memcpy(buf, tmp + 13, data_len);
return data_len;
}
bool
acr122s_abort_command(nfc_device_t *dev)
int
acr122s_abort_command(nfc_device *pnd)
{
if (dev) {
if (pnd) {
#ifndef WIN32
close(DRIVER_DATA(dev)->abort_fds[0]);
close(DRIVER_DATA(dev)->abort_fds[1]);
pipe(DRIVER_DATA(dev)->abort_fds);
close(DRIVER_DATA(pnd)->abort_fds[0]);
close(DRIVER_DATA(pnd)->abort_fds[1]);
pipe(DRIVER_DATA(pnd)->abort_fds);
#else
DRIVER_DATA(dev)->abort_flag = true;
DRIVER_DATA(pnd)->abort_flag = true;
#endif
}
return true;
return NFC_SUCCESS;
}
const struct pn53x_io acr122s_io = {
@ -640,11 +718,11 @@ const struct pn53x_io acr122s_io = {
.receive = acr122s_receive,
};
const struct nfc_driver_t acr122s_driver = {
const struct nfc_driver acr122s_driver = {
.name = ACR122S_DRIVER_NAME,
.probe = acr122s_probe,
.connect = acr122s_connect,
.disconnect = acr122s_disconnect,
.open = acr122s_open,
.close = acr122s_close,
.strerror = pn53x_strerror,
.initiator_init = pn53x_initiator_init,
@ -663,7 +741,8 @@ const struct nfc_driver_t acr122s_driver = {
.target_send_bits = pn53x_target_send_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,
.idle = NULL,

View file

@ -28,14 +28,14 @@
#include <sys/time.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);
void acr122s_disconnect(nfc_device_t *dev);
nfc_device *acr122s_open(const nfc_connstring connstring);
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_receive(nfc_device_t *dev, 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 *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

View file

@ -26,6 +26,9 @@
* 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)
*/
/* vim: set ts=2 sw=2 et: */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif // HAVE_CONFIG_H
@ -33,6 +36,7 @@
#include "arygon.h"
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <sys/param.h>
#include <string.h>
@ -64,7 +68,7 @@
#define DEV_ARYGON_PROTOCOL_TAMA_WAB '3'
#define ARYGON_DEFAULT_SPEED 9600
#define ARYGON_DRIVER_NAME "ARYGON"
#define ARYGON_DRIVER_NAME "arygon"
#define LOG_CATEGORY "libnfc.driver.arygon"
#define DRIVER_DATA(pnd) ((struct arygon_data*)(pnd->driver_data))
@ -80,24 +84,24 @@ struct arygon_data {
#endif
};
static const byte_t arygon_error_none[] = "FF000000\x0d\x0a";
static const byte_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_none[] = "FF000000\x0d\x0a";
static const uint8_t arygon_error_incomplete_command[] = "FF0C0000\x0d\x0a";
static const uint8_t arygon_error_unknown_mode[] = "FF060000\x0d\x0a";
bool arygon_reset_tama (nfc_device_t * pnd);
void arygon_firmware (nfc_device_t * pnd, char * str);
int arygon_reset_tama (nfc_device *pnd);
void arygon_firmware (nfc_device *pnd, char *str);
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
* sending some commands. But using this way to probe devices, we can
* have serious problem with other device on this bus */
#ifndef SERIAL_AUTOPROBE_ENABLED
(void) pnddDevices;
(void) szDevices;
(void) connstrings;
(void) connstrings_len;
*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;
#else /* SERIAL_AUTOPROBE_ENABLED */
*pszDeviceFound = 0;
@ -116,7 +120,10 @@ arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
uart_flush_input (sp);
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_data = malloc(sizeof(struct arygon_data));
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;
#endif
bool res = arygon_reset_tama (pnd);
int res = arygon_reset_tama (pnd);
pn53x_data_free (pnd);
nfc_device_free (pnd);
uart_close (sp);
if(!res)
if(res < 0) {
continue;
}
// ARYGON reader is found
snprintf (pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "Arygon", acPort);
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;
memcpy (connstrings[*pszDeviceFound], connstring, sizeof(nfc_connstring));
(*pszDeviceFound)++;
// Test if we reach the maximum "wanted" devices
if ((*pszDeviceFound) >= szDevices)
if ((*pszDeviceFound) >= connstrings_len)
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;
while ((acPort = acPorts[iDevice++])) {
@ -163,37 +164,100 @@ arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
return true;
}
nfc_device_t *
arygon_connect (const nfc_device_desc_t * pndd)
{
serial_port sp;
nfc_device_t *pnd = NULL;
struct arygon_descriptor {
char port[128];
uint32_t speed;
};
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to connect to: %s at %d bauds.", pndd->acPort, pndd->uiSpeed);
sp = uart_open (pndd->acPort);
int
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)
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)
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))
return NULL;
// We need to flush input to be sure first reply does not comes from older byte transceive
uart_flush_input (sp);
uart_set_speed (sp, pndd->uiSpeed);
uart_set_speed (sp, ndd.speed);
// We have a connection
pnd = nfc_device_new ();
strncpy (pnd->acName, pndd->acDevice, sizeof (pnd->acName));
pnd = nfc_device_new (connstring);
snprintf (pnd->name, sizeof (pnd->name), "%s:%s", ARYGON_DRIVER_NAME, ndd.port);
pnd->driver_data = malloc(sizeof(struct arygon_data));
DRIVER_DATA (pnd)->port = sp;
// Alloc and init chip's data
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;
// empirical tuning
@ -208,16 +272,16 @@ arygon_connect (const nfc_device_desc_t * pndd)
#endif
// Check communication using "Reset TAMA" command
if (!arygon_reset_tama(pnd)) {
nfc_device_free (pnd);
if (arygon_reset_tama(pnd) < 0) {
arygon_close (pnd);
return NULL;
}
char arygon_firmware_version[10];
arygon_firmware (pnd, arygon_firmware_version);
char *pcName;
pcName = strdup (pnd->acName);
snprintf (pnd->acName, sizeof (pnd->acName), "%s %s", pcName, arygon_firmware_version);
pcName = strdup (pnd->name);
snprintf (pnd->name, sizeof (pnd->name), "%s %s", pcName, arygon_firmware_version);
free (pcName);
pn53x_init(pnd);
@ -225,7 +289,7 @@ arygon_connect (const nfc_device_desc_t * pndd)
}
void
arygon_disconnect (nfc_device_t * pnd)
arygon_close (nfc_device *pnd)
{
// Release UART 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_RX_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
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 res = 0;
// Before sending anything, we need to discard from any junk bytes
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;
if (szData > PN53x_NORMAL_FRAME__DATA_MAX_LEN) {
// 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);
pnd->iLastError = EDEVNOTSUP;
return false;
pnd->last_error = NFC_EDEVNOTSUPP;
return pnd->last_error;
}
if (!pn53x_build_frame (abtFrame + 1, &szFrame, pbtData, szData)) {
pnd->iLastError = EINVALARG;
return false;
if ((res = pn53x_build_frame (abtFrame + 1, &szFrame, pbtData, szData)) < 0) {
pnd->last_error = res;
return pnd->last_error;
}
int res = uart_send (DRIVER_DATA (pnd)->port, abtFrame, szFrame + 1, timeout);
if (res != 0) {
if ((res = uart_send (DRIVER_DATA (pnd)->port, abtFrame, szFrame + 1, timeout)) != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
pnd->iLastError = res;
return false;
pnd->last_error = res;
return pnd->last_error;
}
byte_t abtRxBuf[6];
res = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, sizeof (abtRxBuf), 0, timeout);
if (res != 0) {
uint8_t abtRxBuf[6];
if ((res = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, sizeof (abtRxBuf), 0, timeout)) != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to read ACK");
pnd->iLastError = res;
return false;
pnd->last_error = res;
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
} else if (0 == memcmp(arygon_error_unknown_mode, abtRxBuf, sizeof(abtRxBuf))) {
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
// 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);
return false;
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 4, 0, timeout);
return pnd->last_error;
} else {
return false;
return pnd->last_error;
}
return true;
return NFC_SUCCESS;
}
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)
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
return (pn53x_check_communication (pnd)) ? 0 : -1;
return pn53x_check_communication (pnd);
}
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;
void * abort_p = NULL;
void *abort_p = NULL;
#ifndef WIN32
abort_p = &(DRIVER_DATA (pnd)->iAbortFds[1]);
#else
abort_p = &(DRIVER_DATA (pnd)->abort_flag);
abort_p = (void*)&(DRIVER_DATA (pnd)->abort_flag);
#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);
/* iLastError got reset by arygon_abort() */
pnd->iLastError = EOPABORT;
return -1;
/* last_error got reset by arygon_abort() */
pnd->last_error = NFC_EOPABORTED;
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)");
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))) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
// Error frame
uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 3, 0, timeout);
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Application level error detected");
pnd->iLastError = EFRAISERRFRAME;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
} else if ((0xff == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
// Extended frame
// 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])) {
// TODO: Retry
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
// 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) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len);
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
// TFI + PD0 (CC+1)
pnd->iLastError = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
if (pnd->iLastError != 0) {
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
if (pnd->last_error != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
return -1;
return pnd->last_error;
}
if (abtRxBuf[0] != 0xD5) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "TFI Mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
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");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
if (len) {
pnd->iLastError = uart_receive (DRIVER_DATA (pnd)->port, pbtData, len, 0, timeout);
if (pnd->iLastError != 0) {
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, pbtData, len, 0, timeout);
if (pnd->last_error != 0) {
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);
if (pnd->iLastError != 0) {
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
if (pnd->last_error != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
return -1;
return pnd->last_error;
}
byte_t btDCS = (256 - 0xD5);
btDCS -= CHIP_DATA (pnd)->ui8LastCommand + 1;
uint8_t btDCS = (256 - 0xD5);
btDCS -= CHIP_DATA (pnd)->last_command + 1;
for (size_t szPos = 0; szPos < len; szPos++) {
btDCS -= pbtData[szPos];
}
if (btDCS != abtRxBuf[0]) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Data checksum mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
if (0x00 != abtRxBuf[1]) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
// The PN53x command is done and we successfully received the reply
return len;
}
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' };
byte_t abtRx[16];
const uint8_t arygon_firmware_version_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'v' };
uint8_t abtRx[16];
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) {
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Unable to send ARYGON firmware command.");
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) {
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Unable to retrieve ARYGON firmware version.");
return;
}
if ( 0 == memcmp (abtRx, arygon_error_none, 6)) {
byte_t * p = abtRx + 6;
uint8_t *p = abtRx + 6;
unsigned int szData;
sscanf ((const char*)p, "%02x%s", &szData, p);
memcpy (str, p, szData);
@ -450,37 +513,35 @@ arygon_firmware (nfc_device_t * pnd, char * str)
}
}
bool
arygon_reset_tama (nfc_device_t * pnd)
int
arygon_reset_tama (nfc_device *pnd)
{
const byte_t arygon_reset_tama_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'r' };
byte_t abtRx[10]; // Attempted response is 10 bytes long
const uint8_t arygon_reset_tama_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'r' };
uint8_t abtRx[10]; // Attempted response is 10 bytes long
size_t szRx = sizeof(abtRx);
int res;
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
uart_send (DRIVER_DATA (pnd)->port, arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd), &tv);
uart_send (DRIVER_DATA (pnd)->port, arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd), 500);
// 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)
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) {
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)) {
return false;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
return true;
return NFC_SUCCESS;
}
bool
arygon_abort_command (nfc_device_t * pnd)
int
arygon_abort_command (nfc_device *pnd)
{
if (pnd) {
#ifndef WIN32
@ -490,7 +551,7 @@ arygon_abort_command (nfc_device_t * pnd)
DRIVER_DATA (pnd)->abort_flag = true;
#endif
}
return true;
return NFC_SUCCESS;
}
@ -499,12 +560,12 @@ const struct pn53x_io arygon_tama_io = {
.receive = arygon_tama_receive,
};
const struct nfc_driver_t arygon_driver = {
.name = ARYGON_DRIVER_NAME,
.probe = arygon_probe,
.connect = arygon_connect,
.disconnect = arygon_disconnect,
.strerror = pn53x_strerror,
const struct nfc_driver arygon_driver = {
.name = ARYGON_DRIVER_NAME,
.probe = arygon_probe,
.open = arygon_open,
.close = arygon_close,
.strerror = pn53x_strerror,
.initiator_init = pn53x_initiator_init,
.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_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,
// FIXME Implement me
.idle = NULL,
.idle = NULL, // FIXME arygon driver does not support idle()
};

View file

@ -30,14 +30,14 @@
# 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);
void arygon_disconnect (nfc_device_t * pnd);
nfc_device *arygon_open (const nfc_connstring connstring);
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_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDat, struct timeval *timeouta);
int arygon_tama_send (nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout);
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__

View file

@ -32,6 +32,7 @@
#include "pn532_uart.h"
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <unistd.h>
@ -44,11 +45,11 @@
#include "uart.h"
#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"
int pn532_uart_ack (nfc_device_t * pnd);
int pn532_uart_wakeup (nfc_device_t * pnd);
int pn532_uart_ack (nfc_device *pnd);
int pn532_uart_wakeup (nfc_device *pnd);
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))
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
* sending some PN53x commands. But using this way to probe devices, we can
* have serious problem with other device on this bus */
#ifndef SERIAL_AUTOPROBE_ENABLED
(void) pnddDevices;
(void) szDevices;
(void) connstrings;
(void) connstrings_len;
*pszDeviceFound = 0;
log_put (LOG_CATEGORY, NFC_PRIORITY_INFO, "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
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)) {
// We need to flush input to be sure first reply does not comes from older byte transceive
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);
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_data = malloc(sizeof(struct pn532_uart_data));
DRIVER_DATA (pnd)->port = sp;
@ -113,29 +116,22 @@ pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps
#endif
// Check communication using "Diagnose" command, with "Communication test" (0x00)
bool res = pn53x_check_communication (pnd);
if(!res) {
nfc_perror (pnd, "pn53x_check_communication");
}
int res = pn53x_check_communication (pnd);
pn53x_data_free (pnd);
nfc_device_free (pnd);
uart_close (sp);
if(!res) {
if(res < 0) {
continue;
}
snprintf (pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "PN532", acPort);
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;
memcpy (connstrings[*pszDeviceFound], connstring, sizeof (nfc_connstring));
(*pszDeviceFound)++;
// Test if we reach the maximum "wanted" devices
if ((*pszDeviceFound) >= szDevices)
if ((*pszDeviceFound) >= connstrings_len)
break;
}
}
iDevice = 0;
while ((acPort = acPorts[iDevice++])) {
free ((void*)acPort);
@ -145,33 +141,96 @@ pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps
return true;
}
nfc_device_t *
pn532_uart_connect (const nfc_device_desc_t * pndd)
{
serial_port sp;
nfc_device_t *pnd = NULL;
struct pn532_uart_descriptor {
char port[128];
uint32_t speed;
};
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to connect to: %s at %d bauds.", pndd->acPort, pndd->uiSpeed);
sp = uart_open (pndd->acPort);
int
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)
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)
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))
return NULL;
// We need to flush input to be sure first reply does not comes from older byte transceive
uart_flush_input (sp);
uart_set_speed (sp, pndd->uiSpeed);
uart_set_speed (sp, ndd.speed);
// We have a connection
pnd = nfc_device_new ();
strncpy (pnd->acName, pndd->acDevice, DEVICE_NAME_LENGTH - 1);
pnd->acName[DEVICE_NAME_LENGTH - 1] = '\0';
pnd = nfc_device_new (connstring);
snprintf (pnd->name, sizeof (pnd->name), "%s:%s", PN532_UART_DRIVER_NAME, ndd.port);
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
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
@ -191,9 +250,9 @@ pn532_uart_connect (const nfc_device_desc_t * pndd)
#endif
// 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");
pn532_uart_disconnect(pnd);
pn532_uart_close (pnd);
return NULL;
}
@ -202,7 +261,7 @@ pn532_uart_connect (const nfc_device_desc_t * pndd)
}
void
pn532_uart_disconnect (nfc_device_t * pnd)
pn532_uart_close (nfc_device *pnd)
{
// Release UART port
uart_close (DRIVER_DATA(pnd)->port);
@ -218,40 +277,38 @@ pn532_uart_disconnect (nfc_device_t * pnd)
}
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. */
const byte_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);
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), 0);
CHIP_DATA(pnd)->power_mode = NORMAL; // PN532 should now be awake
return res;
}
#define PN532_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
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 res = 0;
// Before sending anything, we need to discard from any junk bytes
uart_flush_input (DRIVER_DATA(pnd)->port);
switch (CHIP_DATA(pnd)->power_mode) {
case LOWVBAT: {
/** PN532C106 wakeup. */
if (-1 == pn532_uart_wakeup(pnd)) {
return false;
if ((res = pn532_uart_wakeup(pnd)) < 0) {
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
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
if (!pn53x_SAMConfiguration (pnd, 0x01, &tv)) {
return false;
if ((res = pn53x_SAMConfiguration (pnd, 0x01, 1000)) < 0) {
return res;
}
}
break;
case POWERDOWN: {
if (-1 == pn532_uart_wakeup(pnd)) {
return false;
if ((res = pn532_uart_wakeup(pnd)) < 0) {
return res;
}
}
break;
@ -260,43 +317,43 @@ pn532_uart_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData
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;
if (!pn53x_build_frame (abtFrame, &szFrame, pbtData, szData)) {
pnd->iLastError = EINVALARG;
return false;
if ((res = pn53x_build_frame (abtFrame, &szFrame, pbtData, szData)) < 0) {
pnd->last_error = res;
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) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
pnd->iLastError = res;
return false;
pnd->last_error = res;
return pnd->last_error;
}
byte_t abtRxBuf[6];
uint8_t abtRxBuf[6];
res = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 6, 0, timeout);
if (res != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to read ACK");
pnd->iLastError = res;
return false;
pnd->last_error = res;
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
} else {
return false;
return pnd->last_error;
}
return true;
return NFC_SUCCESS;
}
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;
void * abort_p = NULL;
void *abort_p = NULL;
#ifndef WIN32
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);
#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)) {
pn532_uart_ack (pnd);
return -1;
if (abort_p && (NFC_EOPABORTED == pnd->last_error)) {
return pn532_uart_ack (pnd);
}
if (pnd->iLastError != 0) {
if (pnd->last_error != 0) {
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))) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
// 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");
pnd->iLastError = EFRAISERRFRAME;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
} else if ((0xff == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
// Extended frame
pnd->iLastError = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout);
if (pnd->iLastError) return -1;
pnd->last_error = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout);
if (pnd->last_error) return pnd->last_error;
// (abtRxBuf[0] << 8) + abtRxBuf[1] (LEN) include TFI + (CC+1)
len = (abtRxBuf[0] << 8) + abtRxBuf[1] - 2;
if (((abtRxBuf[0] + abtRxBuf[1] + abtRxBuf[2]) % 256) != 0) {
// TODO: Retry
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
} else {
// Normal frame
if (256 != (abtRxBuf[3] + abtRxBuf[4])) {
// TODO: Retry
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
// 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) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len);
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
// TFI + PD0 (CC+1)
pnd->iLastError = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout);
if (pnd->iLastError != 0) {
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
if (pnd->last_error != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
return -1;
return pnd->last_error;
}
if (abtRxBuf[0] != 0xD5) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "TFI Mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
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");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
if (len) {
pnd->iLastError = uart_receive (DRIVER_DATA(pnd)->port, pbtData, len, 0, timeout);
if (pnd->iLastError != 0) {
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, pbtData, len, 0, timeout);
if (pnd->last_error != 0) {
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);
if (pnd->iLastError != 0) {
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
if (pnd->last_error != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
return -1;
return pnd->last_error;
}
byte_t btDCS = (256 - 0xD5);
btDCS -= CHIP_DATA (pnd)->ui8LastCommand + 1;
uint8_t btDCS = (256 - 0xD5);
btDCS -= CHIP_DATA (pnd)->last_command + 1;
for (size_t szPos = 0; szPos < len; szPos++) {
btDCS -= pbtData[szPos];
}
if (btDCS != abtRxBuf[0]) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Data checksum mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
if (0x00 != abtRxBuf[1]) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
// The PN53x command is done and we successfully received the reply
return len;
}
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 (-1 == pn532_uart_wakeup(pnd)) {
return -1;
if ((res = pn532_uart_wakeup(pnd)) < 0) {
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
pn532_uart_abort_command (nfc_device_t * pnd)
int
pn532_uart_abort_command (nfc_device *pnd)
{
if (pnd) {
#ifndef WIN32
@ -437,7 +494,7 @@ pn532_uart_abort_command (nfc_device_t * pnd)
DRIVER_DATA (pnd)->abort_flag = true;
#endif
}
return true;
return NFC_SUCCESS;
}
const struct pn53x_io pn532_uart_io = {
@ -445,12 +502,12 @@ const struct pn53x_io pn532_uart_io = {
.receive = pn532_uart_receive,
};
const struct nfc_driver_t pn532_uart_driver = {
.name = PN532_UART_DRIVER_NAME,
.probe = pn532_uart_probe,
.connect = pn532_uart_connect,
.disconnect = pn532_uart_disconnect,
.strerror = pn53x_strerror,
const struct nfc_driver pn532_uart_driver = {
.name = PN532_UART_DRIVER_NAME,
.probe = pn532_uart_probe,
.open = pn532_uart_open,
.close = pn532_uart_close,
.strerror = pn53x_strerror,
.initiator_init = pn53x_initiator_init,
.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_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,
.idle = pn53x_idle,

View file

@ -29,13 +29,13 @@
# 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);
void pn532_uart_disconnect (nfc_device_t * pnd);
bool pn532_uart_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout);
int pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struct timeval *timeout);
nfc_device *pn532_uart_open (const nfc_connstring connstring);
void pn532_uart_close (nfc_device *pnd);
int pn532_uart_send (nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int 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__

View file

@ -32,10 +32,11 @@
Thanks to d18c7db and Okko for example code
*/
#include <sys/select.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/select.h>
#include <errno.h>
#ifndef _WIN32
// 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 "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 USB_INFINITE_TIMEOUT 0
#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 {
UNKNOWN,
NXP_PN531,
@ -117,21 +87,12 @@ struct pn53x_usb_data {
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_init (nfc_device_t *pnd);
int pn53x_usb_init (nfc_device *pnd);
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;
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);
int res = usb_bulk_read (data->pudh, data->uiEndPointIn, (char *) abtRx, szRx, timeout);
if (res > 0) {
LOG_HEX ("RX", abtRx, res);
} 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
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);
int timeout_ms = USB_INFINITE_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);
int res = usb_bulk_write (data->pudh, data->uiEndPointOut, (char *) abtTx, szTx, timeout);
if (res > 0) {
// 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) {
usb_bulk_write (data->pudh, data->uiEndPointOut, "\0", 0, timeout_ms);
usb_bulk_write (data->pudh, data->uiEndPointOut, "\0", 0, timeout);
}
} else {
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;
}
int pn53x_usb_ack (nfc_device_t * pnd);
int pn53x_usb_ack (nfc_device *pnd);
// Find transfer endpoints for bulk transfers
void
@ -222,7 +179,7 @@ pn53x_usb_get_end_points (struct usb_device *dev, struct pn53x_usb_data *data)
}
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 ();
@ -275,13 +232,13 @@ pn53x_usb_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * psz
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);
pnddDevices[*pszDeviceFound].pcDriver = PN53X_USB_DRIVER_NAME;
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
snprintf (connstrings[*pszDeviceFound], sizeof(nfc_connstring), "%s:%s:%s", PN53X_USB_DRIVER_NAME, bus->dirname, dev->filename);
(*pszDeviceFound)++;
// Test if we reach the maximum "wanted" devices
if ((*pszDeviceFound) == szDevices) {
if ((*pszDeviceFound) == connstrings_len) {
return true;
}
}
@ -292,6 +249,38 @@ pn53x_usb_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * psz
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
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;
}
nfc_device_t *
pn53x_usb_connect (const nfc_device_desc_t *pndd)
nfc_device *
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 = {
.pudh = NULL,
.uiEndPointIn = 0,
@ -330,95 +326,118 @@ pn53x_usb_connect (const nfc_device_desc_t *pndd)
};
struct usb_bus *bus;
struct usb_device *dev;
uint32_t uiBusIndex;
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 (dev = bus->devices; dev; dev = dev->next, uiBusIndex--) {
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Checking device %04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
if (uiBusIndex == 0) {
// 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
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;
if (connstring_decode_level > 1) {
// A specific bus have been specified
if (0 != strcmp (bus->dirname, desc.dirname))
continue;
}
for (dev = bus->devices; dev; dev = dev->next) {
if (connstring_decode_level > 2) {
// A specific dev have been specified
if (0 != strcmp (dev->filename, desc.filename))
continue;
}
// 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
return NULL;
goto free_mem;
error:
// Free allocated structure on error.
nfc_device_free (pnd);
return NULL;
free_mem:
free (desc.dirname);
free (desc.filename);
return pnd;
}
void
pn53x_usb_disconnect (nfc_device_t * pnd)
pn53x_usb_close (nfc_device *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)
bool
pn53x_usb_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout)
int
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;
int res = 0;
pn53x_build_frame (abtFrame, &szFrame, pbtData, szData);
int res = pn53x_usb_bulk_write (DRIVER_DATA (pnd), abtFrame, szFrame, timeout);
if (res < 0) {
pnd->iLastError = ECOMIO;
return false;
if ((res = pn53x_usb_bulk_write (DRIVER_DATA (pnd), abtFrame, szFrame, timeout)) < 0) {
pnd->last_error = res;
return pnd->last_error;
}
byte_t abtRxBuf[PN53X_USB_BUFFER_LEN];
res = pn53x_usb_bulk_read (DRIVER_DATA (pnd), abtRxBuf, sizeof (abtRxBuf), timeout);
if (res < 0) {
pnd->iLastError = ECOMIO;
uint8_t abtRxBuf[PN53X_USB_BUFFER_LEN];
if ((res = pn53x_usb_bulk_read (DRIVER_DATA (pnd), abtRxBuf, sizeof (abtRxBuf), timeout)) < 0) {
pnd->last_error = res;
// try to interrupt current device state
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
} else {
// 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
// packet.
// 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 < 0) {
pnd->iLastError = ECOMIO;
if ((res = pn53x_usb_bulk_write (DRIVER_DATA (pnd), (uint8_t *)pn53x_nack_frame, sizeof(pn53x_nack_frame), timeout)) < 0) {
pnd->last_error = res;
// try to interrupt current device state
pn53x_usb_ack(pnd);
return false;
return pnd->last_error;
}
}
return true;
return NFC_SUCCESS;
}
#define USB_TIMEOUT_PER_PASS 200
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;
off_t offset = 0;
byte_t abtRxBuf[PN53X_USB_BUFFER_LEN];
uint8_t abtRxBuf[PN53X_USB_BUFFER_LEN];
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.
*/
const struct timeval fixed_timeout = {
.tv_sec = 0,
.tv_usec = 250000,
};
struct timeval remaining_time, usb_timeout;
if (timeout) {
remaining_time = *timeout;
}
int usb_timeout;
int remaining_time = timeout;
read:
if (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
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;
}
if (timeout == USB_INFINITE_TIMEOUT) {
usb_timeout = USB_TIMEOUT_PER_PASS;
} else {
// No user-provided timeout, we will wait infinitely but we need nfc_abort_command() mecanism.
usb_timeout = fixed_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
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;
return -1;
}
res = pn53x_usb_bulk_read (DRIVER_DATA (pnd), abtRxBuf, sizeof (abtRxBuf), &usb_timeout);
res = pn53x_usb_bulk_read (DRIVER_DATA (pnd), abtRxBuf, sizeof (abtRxBuf), usb_timeout);
if (res == -USB_TIMEDOUT) {
if (DRIVER_DATA (pnd)->abort_flag) {
DRIVER_DATA (pnd)->abort_flag = false;
pn53x_usb_ack (pnd);
pnd->iLastError = EOPABORT;
return -1;
pnd->last_error = NFC_EOPABORTED;
return pnd->last_error;
} else {
goto read;
}
}
if (res < 0) {
pnd->iLastError = ECOMIO;
pnd->last_error = res;
// try to interrupt current device state
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))) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
offset += 3;
if ((0x01 == abtRxBuf[offset]) && (0xff == abtRxBuf[offset + 1])) {
// Error frame
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Application level error detected");
pnd->iLastError = EFRAISERRFRAME;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
} else if ((0xff == abtRxBuf[offset]) && (0xff == abtRxBuf[offset + 1])) {
// Extended frame
offset += 2;
@ -575,8 +578,8 @@ read:
if (((abtRxBuf[offset] + abtRxBuf[offset + 1] + abtRxBuf[offset + 2]) % 256) != 0) {
// TODO: Retry
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
offset += 3;
} else {
@ -584,8 +587,8 @@ read:
if (256 != (abtRxBuf[offset] + abtRxBuf[offset + 1])) {
// TODO: Retry
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
// abtRxBuf[3] (LEN) include TFI + (CC+1)
@ -595,75 +598,76 @@ read:
if (len > szDataLen) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len);
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
// TFI + PD0 (CC+1)
if (abtRxBuf[offset] != 0xD5) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "TFI Mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
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");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
offset += 1;
memcpy (pbtData, abtRxBuf + offset, len);
offset += len;
byte_t btDCS = (256 - 0xD5);
btDCS -= CHIP_DATA (pnd)->ui8LastCommand + 1;
uint8_t btDCS = (256 - 0xD5);
btDCS -= CHIP_DATA (pnd)->last_command + 1;
for (size_t szPos = 0; szPos < len; szPos++) {
btDCS -= pbtData[szPos];
}
if (btDCS != abtRxBuf[offset]) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Data checksum mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
offset += 1;
if (0x00 != abtRxBuf[offset]) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
pnd->iLastError = ECOMIO;
return -1;
pnd->last_error = NFC_EIO;
return pnd->last_error;
}
// The PN53x command is done and we successfully received the reply
pnd->iLastError = 0;
pnd->last_error = 0;
return len;
}
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
pn53x_usb_init (nfc_device_t *pnd)
int
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...
//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 };
pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL, NULL);
const uint8_t abtCmd[] = { GetFirmwareVersion };
pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, 0, 0);
// ...and we don't care about error
pnd->iLastError = 0;
pnd->last_error = 0;
if (SONY_RCS360 == DRIVER_DATA (pnd)->model) {
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "SONY RC-S360 initialization.");
const byte_t abtCmd2[] = { 0x18, 0x01 };
pn53x_transceive (pnd, abtCmd2, sizeof (abtCmd2), NULL, NULL, NULL);
const uint8_t abtCmd2[] = { 0x18, 0x01 };
pn53x_transceive (pnd, abtCmd2, sizeof (abtCmd2), NULL, 0, 0);
pn53x_usb_ack (pnd);
}
if (!pn53x_init (pnd))
return false;
if ((res = pn53x_init (pnd)) < 0)
return res;
if (ASK_LOGO == DRIVER_DATA (pnd)->model) {
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));
}
return true;
return NFC_SUCCESS;
}
bool
pn53x_usb_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable)
int
pn53x_usb_set_property_bool (nfc_device *pnd, const nfc_property property, const bool bEnable)
{
if (!pn53x_configure (pnd, ndo, bEnable))
return false;
int res = 0;
if ((res = pn53x_set_property_bool (pnd, property, bEnable)) < 0)
return res;
switch (DRIVER_DATA (pnd)->model) {
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 */
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)))
return false;
if ((res = pn53x_write_register (pnd, PN53X_SFR_P3, _BV(P31) | _BV(P34), bEnable ? _BV (P34) : _BV (P31))) < 0)
return NFC_ECHIP;
}
break;
case SCM_SCL3711:
if (NDO_ACTIVATE_FIELD == ndo) {
if (NP_ACTIVATE_FIELD == property) {
// Switch on/off LED according to ACTIVATE_FIELD option
if (!pn53x_write_register (pnd, PN53X_SFR_P3, _BV (P32), bEnable ? 0 : _BV (P32)))
return false;
if ((res = pn53x_write_register (pnd, PN53X_SFR_P3, _BV (P32), bEnable ? 0 : _BV (P32))) < 0)
return res;
}
break;
default:
break;
}
return true;
return NFC_SUCCESS;
}
bool
pn53x_usb_abort_command (nfc_device_t * pnd)
int
pn53x_usb_abort_command (nfc_device *pnd)
{
DRIVER_DATA (pnd)->abort_flag = true;
return true;
return NFC_SUCCESS;
}
const struct pn53x_io pn53x_usb_io = {
@ -743,12 +748,12 @@ const struct pn53x_io pn53x_usb_io = {
.receive = pn53x_usb_receive,
};
const struct nfc_driver_t pn53x_usb_driver = {
.name = PN53X_USB_DRIVER_NAME,
.probe = pn53x_usb_probe,
.connect = pn53x_usb_connect,
.disconnect = pn53x_usb_disconnect,
.strerror = pn53x_strerror,
const struct nfc_driver pn53x_usb_driver = {
.name = PN53X_USB_DRIVER_NAME,
.probe = pn53x_usb_probe,
.open = pn53x_usb_open,
.close = pn53x_usb_close,
.strerror = pn53x_strerror,
.initiator_init = pn53x_initiator_init,
.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_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,
.idle = pn53x_idle,

View file

@ -23,18 +23,20 @@
*/
#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);
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);
#include "nfc-internal.h"
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__

View file

@ -32,30 +32,30 @@
#include <nfc/nfc.h>
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;
do {
bt = *pbtData++;
bt = (bt ^ (byte_t) (wCrc & 0x00FF));
bt = (bt ^ (uint8_t) (wCrc & 0x00FF));
bt = (bt ^ (bt << 4));
wCrc = (wCrc >> 8) ^ ((uint32_t) bt << 8) ^ ((uint32_t) bt << 3) ^ ((uint32_t) bt >> 4);
} while (--szLen);
*pbtCrc++ = (byte_t) (wCrc & 0xFF);
*pbtCrc = (byte_t) ((wCrc >> 8) & 0xFF);
*pbtCrc++ = (uint8_t) (wCrc & 0xFF);
*pbtCrc = (uint8_t) ((wCrc >> 8) & 0xFF);
}
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);
}
byte_t *
iso14443a_locate_historical_bytes (byte_t * pbtAts, size_t szAts, size_t * pszTk)
uint8_t *
iso14443a_locate_historical_bytes (uint8_t *pbtAts, size_t szAts, size_t *pszTk)
{
if (szAts) {
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)
*/
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) {
case 7:

View file

@ -17,9 +17,10 @@
#include "config.h"
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
#include <fcntl.h>
#include <log4c.h>
#include <inttypes.h>
#include "log.h"
@ -31,7 +32,7 @@ log_init (void)
int res = 0;
if (__log_init_counter == 0) {
res = log4c_init ();
res = 0;
}
if (!res) {
__log_init_counter++;
@ -45,7 +46,7 @@ log_fini (void)
int res = 0;
if (__log_init_counter >= 1) {
if (__log_init_counter == 1) {
res = log4c_fini ();
res = 0;
}
__log_init_counter--;
} else {
@ -55,12 +56,12 @@ log_fini (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);
if (log4c_category_is_priority_enabled (cat, priority)) {
va_list va;
va_start (va, format);
log4c_category_vlog (cat, priority, format, va);
}
va_list va;
va_start (va, format);
printf ("%s\t%s\t", priority, category);
vprintf (format, va);
printf ("\n");
va_end (va);
}

View file

@ -18,69 +18,44 @@
#ifndef __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
#include <log4c.h>
int log_init (void);
int log_fini (void);
void log_put (char *category, int priority, char *format, ...);
#define NFC_PRIORITY_FATAL LOG4C_PRIORITY_FATAL
#define NFC_PRIORITY_ALERT LOG4C_PRIORITY_ALERT
#define NFC_PRIORITY_CRIT LOG4C_PRIORITY_CRIT
#define NFC_PRIORITY_ERROR LOG4C_PRIORITY_ERROR
#define NFC_PRIORITY_WARN LOG4C_PRIORITY_WARN
#define NFC_PRIORITY_NOTICE LOG4C_PRIORITY_NOTICE
#define NFC_PRIORITY_INFO LOG4C_PRIORITY_INFO
#define NFC_PRIORITY_DEBUG LOG4C_PRIORITY_DEBUG
#define NFC_PRIORITY_TRACE LOG4C_PRIORITY_TRACE
#elif defined(DEBUG) /* no available log4c but debug is enabled */
#define LOGGING 1
#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 { \
fprintf(stderr, "%s - ", category); \
fprintf(stderr, format, ##__VA_ARGS__); \
fprintf(stderr, "\n"); \
} 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
#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
#if defined DEBUG
// User want debug features
#define LOGGING 1
int log_init (void);
int log_fini (void);
void log_put (char *category, char *priority, char *format, ...);
#define NFC_PRIORITY_FATAL "fatal"
#define NFC_PRIORITY_ALERT "alert"
#define NFC_PRIORITY_CRIT "critical"
#define NFC_PRIORITY_ERROR "error"
#define NFC_PRIORITY_WARN "warning"
#define NFC_PRIORITY_NOTICE "notice"
#define NFC_PRIORITY_INFO "info"
#define NFC_PRIORITY_DEBUG "debug"
#define NFC_PRIORITY_TRACE "trace"
#else
// No logging
#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 /* HAS_LOG4C, DEBUG */
/**
* @macro LOG_HEX

View file

@ -30,7 +30,7 @@
#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,
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,
@ -53,14 +53,14 @@ static const byte_t ByteMirror[256] = {
0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
byte_t
mirror (byte_t bt)
uint8_t
mirror (uint8_t bt)
{
return ByteMirror[bt];
}
void
mirror_bytes (byte_t * pbts, size_t szLen)
mirror_bytes (uint8_t *pbts, size_t szLen)
{
size_t szByteNr;
@ -73,13 +73,13 @@ mirror_bytes (byte_t * pbts, size_t szLen)
uint32_t
mirror32 (uint32_t ui32Bits)
{
mirror_bytes ((byte_t *) & ui32Bits, 4);
mirror_bytes ((uint8_t *) & ui32Bits, 4);
return ui32Bits;
}
uint64_t
mirror64 (uint64_t ui64Bits)
{
mirror_bytes ((byte_t *) & ui64Bits, 8);
mirror_bytes ((uint8_t *) & ui64Bits, 8);
return ui64Bits;
}

View file

@ -29,9 +29,9 @@
# include <nfc/nfc-types.h>
byte_t mirror (byte_t bt);
uint8_t mirror (uint8_t bt);
uint32_t mirror32 (uint32_t ui32Bits);
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_

View file

@ -19,12 +19,13 @@
/**
* @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: */
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
@ -32,10 +33,10 @@
#include "nfc-internal.h"
nfc_device_t *
nfc_device_new (void)
nfc_device *
nfc_device_new (const nfc_connstring connstring)
{
nfc_device_t *res = malloc (sizeof (*res));
nfc_device *res = malloc (sizeof (*res));
if (!res) {
err (EXIT_FAILURE, "nfc_device_new: malloc");
@ -49,7 +50,8 @@ nfc_device_new (void)
res->bPar = false;
res->bEasyFraming = false;
res->bAutoIso14443_4 = false;
res->iLastError = 0;
res->last_error = 0;
memcpy (res->connstring, connstring, sizeof (res->connstring));
res->driver_data = NULL;
res->chip_data = NULL;
@ -57,7 +59,7 @@ nfc_device_new (void)
}
void
nfc_device_free (nfc_device_t *nfc_device)
nfc_device_free (nfc_device *nfc_device)
{
if (nfc_device) {
free (nfc_device->driver_data);

View file

@ -28,26 +28,26 @@
#include "iso7816.h"
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];
size_t szRx = sizeof(abtRx);
byte_t abtTx[ISO7816_SHORT_C_APDU_MAX_LEN];
uint8_t abtRx[ISO7816_SHORT_R_APDU_MAX_LEN];
int szRx;
uint8_t abtTx[ISO7816_SHORT_C_APDU_MAX_LEN];
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;
}
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 (!nfc_target_send_bytes(pnd, abtTx, res, NULL)) {
if (nfc_target_send_bytes(pnd, abtTx, res, 0) < 0) {
return -1;
}
}
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;
}
}

View file

@ -23,39 +23,38 @@
*/
#include <nfc/nfc.h>
#include <nfc/nfc-emulation.h>
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) {
case NMT_ISO14443B: {
// 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;
}
break;
case NMT_ISO14443BI: {
// APGEN
*ppbtInitiatorData = (byte_t *) "\x01\x0b\x3f\x80";
*ppbtInitiatorData = (uint8_t *) "\x01\x0b\x3f\x80";
*pszInitiatorData = 4;
}
break;
case NMT_ISO14443B2SR: {
// Get_UID
*ppbtInitiatorData = (byte_t *) "\x0b";
*ppbtInitiatorData = (uint8_t *) "\x0b";
*pszInitiatorData = 1;
}
break;
case NMT_ISO14443B2CT: {
// SELECT-ALL
*ppbtInitiatorData = (byte_t *) "\x9F\xFF\xFF";
*ppbtInitiatorData = (uint8_t *) "\x9F\xFF\xFF";
*pszInitiatorData = 3;
}
break;
case NMT_FELICA: {
// 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;
}
break;

View file

@ -23,24 +23,25 @@
*/
#ifndef __NFC_INTERNAL_H__
# define __NFC_INTERNAL_H__
#define __NFC_INTERNAL_H__
# include <nfc/nfc-types.h>
# include <stdbool.h>
# include <err.h>
#include <stdbool.h>
#include <err.h>
# include <sys/time.h>
#include "nfc/nfc.h"
#include "log.h"
/**
* @macro HAL
* @brief Execute corresponding driver function if exists.
*/
#define HAL( FUNCTION, ... ) pnd->iLastError = 0; \
#define HAL( FUNCTION, ... ) pnd->last_error = 0; \
if (pnd->driver->FUNCTION) { \
return pnd->driver->FUNCTION( __VA_ARGS__ ); \
} else { \
pnd->iLastError = EDEVNOTSUP; \
pnd->last_error = NFC_EDEVNOTSUPP; \
return false; \
}
@ -125,40 +126,72 @@
#endif
struct nfc_driver_t {
struct nfc_driver {
const char *name;
bool (*probe)(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
nfc_device_t * (*connect)(const nfc_device_desc_t * pndd);
void (*disconnect)(nfc_device_t * pnd);
const char *(*strerror)(const nfc_device_t * pnd);
bool (*probe)(nfc_connstring connstrings[], size_t connstrings_len, size_t * pszDeviceFound);
struct nfc_device *(*open) (const nfc_connstring connstring);
void (*close) (struct nfc_device *pnd);
const char *(*strerror) (const struct nfc_device *pnd);
bool (*initiator_init) (nfc_device_t * 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);
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);
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);
bool (*initiator_deselect_target) (nfc_device_t * 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);
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);
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);
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_init) (struct nfc_device *pnd);
int (*initiator_select_passive_target) (struct nfc_device *pnd, const nfc_modulation nm, const uint8_t * pbtInitData, const size_t szInitData, nfc_target * 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);
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);
int (*initiator_deselect_target) (struct nfc_device *pnd);
int (*initiator_transceive_bytes) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTx, uint8_t * pbtRx, size_t * pszRx, int timeout);
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);
int (*initiator_transceive_bytes_timed) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTx, uint8_t * pbtRx, 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);
bool (*target_send_bytes) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, struct timeval *timeout);
bool (*target_receive_bytes) (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
bool (*target_send_bits) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar);
bool (*target_receive_bits) (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
int (*target_init) (struct nfc_device *pnd, nfc_target * pnt, uint8_t * pbtRx, const size_t szRx, int timeout);
int (*target_send_bytes) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTx, int timeout);
int (*target_receive_bytes) (struct nfc_device *pnd, uint8_t * pbtRx, const size_t szRxLen, int timeout);
int (*target_send_bits) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTxBits, const uint8_t * pbtTxPar);
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);
bool (*idle) (nfc_device_t * pnd);
int (*abort_command) (struct nfc_device *pnd);
int (*idle) (struct nfc_device *pnd);
};
nfc_device_t *nfc_device_new (void);
void nfc_device_free (nfc_device_t *nfc_device);
# define DEVICE_NAME_LENGTH 256
# 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__

File diff suppressed because it is too large Load diff

View file

@ -21,5 +21,5 @@
<layout name="basic" type="basic"/>
<layout name="dated" type="dated"/>
<category name="libnfc" priority="trace" appender="stdout"/>
<category name="libnfc" priority="trace" appender="stderr"/>
</log4c>

View file

@ -9,7 +9,9 @@ TESTS_ENVIRONMENT = NO_MAKE=yes CUTTER="$(CUTTER)"
cutter_unit_test_libs = \
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_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_LIBADD = $(top_builddir)/libnfc/libnfc.la
test_dep_la_SOURCES = test_dep.c
test_dep_la_LIBADD = $(top_builddir)/libnfc/libnfc.la
test_dep_active_la_SOURCES = test_dep_active.c
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_LIBADD = $(top_builddir)/libnfc/libnfc.la

View file

@ -14,40 +14,42 @@ void
test_access_storm (void)
{
int n = NTESTS;
nfc_device_desc_t devices[MAX_DEVICE_COUNT];
size_t device_count, ref_device_count, target_count;
bool res;
nfc_connstring connstrings[MAX_DEVICE_COUNT];
int res = 0;
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)
cut_omit ("No NFC device found");
while (n) {
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"));
for (i = 0; i < device_count; i++) {
nfc_device_t *device;
nfc_target_t ant[MAX_TARGET_COUNT];
nfc_device *device;
nfc_target ant[MAX_TARGET_COUNT];
device = nfc_connect (&(devices[i]));
cut_assert_not_null (device, cut_message ("nfc_connect"));
device = nfc_open (NULL, connstrings[i]);
cut_assert_not_null (device, cut_message ("nfc_open"));
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,
.nbr = NBR_106,
};
res = nfc_initiator_list_passive_targets(device, nm, ant, MAX_TARGET_COUNT, &target_count);
cut_assert_true (res, cut_message ("nfc_initiator_list_passive_targets"));
res = nfc_initiator_list_passive_targets(device, nm, ant, MAX_TARGET_COUNT);
cut_assert_operator_int (res, >=, 0, cut_message ("nfc_initiator_list_passive_targets"));
nfc_disconnect (device);
nfc_close (device);
}
n--;
}
nfc_exit (NULL);
}

View file

@ -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
View 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
View 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"));
}

View 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;
}
}

View file

@ -9,38 +9,40 @@
void
test_register_endianness (void)
{
nfc_device_desc_t devices[MAX_DEVICE_COUNT];
size_t device_count;
bool res;
nfc_connstring connstrings[MAX_DEVICE_COUNT];
int res = 0;
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)
cut_omit ("No NFC device found");
nfc_device_t *device;
nfc_device *device;
device = nfc_connect (&(devices[0]));
cut_assert_not_null (device, cut_message ("nfc_connect"));
device = nfc_open (NULL, connstrings[0]);
cut_assert_not_null (device, cut_message ("nfc_open"));
uint8_t value;
/* Set a 0xAA test value in writable register memory to test register access */
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 */
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"));
/* Set a 0x55 test value in writable register memory to test register access */
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 */
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"));
nfc_disconnect (device);
nfc_close (device);
nfc_exit (NULL);
}

View file

@ -10,28 +10,30 @@
void
test_register_endianness (void)
{
nfc_device_desc_t devices[MAX_DEVICE_COUNT];
size_t device_count;
bool res;
nfc_connstring connstrings[MAX_DEVICE_COUNT];
int res = 0;
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)
cut_omit ("No NFC device found");
nfc_device_t *device;
nfc_device *device;
device = nfc_connect (&(devices[0]));
cut_assert_not_null (device, cut_message ("nfc_connect"));
device = nfc_open (NULL, connstrings[0]);
cut_assert_not_null (device, cut_message ("nfc_open"));
uint8_t value;
/* Read valid XRAM memory */
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 */
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);
}

View file

@ -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
nfc-utils.c

View file

@ -1,10 +1,10 @@
bin_PROGRAMS = \
nfc-emulate-forum-tag2 \
nfc-emulate-forum-tag4 \
nfc-list \
nfc-mfclassic \
nfc-mfsetuid \
nfc-mfultralight \
nfc-probe \
nfc-read-forum-tag3 \
nfc-relay-picc
@ -18,10 +18,6 @@ noinst_LTLIBRARIES = libnfcutils.la
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_LDADD = $(top_builddir)/libnfc/libnfc.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_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_LDADD = $(top_builddir)/libnfc/libnfc.la \
libnfcutils.la
@ -57,9 +57,4 @@ dist_man_MANS = \
nfc-mfultralight.1 \
nfc-relay-picc.1
if HAS_LOG4C
AM_CFLAGS += @log4c_CFLAGS@
LIBADD = @log4c_LIBS@
endif
EXTRA_DIST = CMakeLists.txt

View file

@ -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.
*/
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 szParamLen;
byte_t abtCmd[265];
bool bEasyFraming;
uint8_t abtCmd[265];
//bool bEasyFraming;
abtCmd[0] = mc; // The MIFARE Classic command
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
case MC_AUTH_A:
case MC_AUTH_B:
szParamLen = sizeof (mifare_param_auth);
szParamLen = sizeof (struct mifare_param_auth);
break;
// Data command
case MC_WRITE:
szParamLen = sizeof (mifare_param_data);
szParamLen = sizeof (struct mifare_param_data);
break;
// Value command
case MC_DECREMENT:
case MC_INCREMENT:
case MC_TRANSFER:
szParamLen = sizeof (mifare_param_value);
szParamLen = sizeof (struct mifare_param_value);
break;
// 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
if (szParamLen)
memcpy (abtCmd + 2, (byte_t *) pmp, szParamLen);
memcpy (abtCmd + 2, (uint8_t *) pmp, szParamLen);
bEasyFraming = pnd->bEasyFraming;
if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) {
nfc_perror (pnd, "nfc_configure");
// FIXME: Save and restore bEasyFraming
// bEasyFraming = nfc_device_get_property_bool (pnd, NP_EASY_FRAMING, &bEasyFraming);
if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, true) < 0) {
nfc_perror (pnd, "nfc_device_set_property_bool");
return false;
}
// Fire the mifare command
if (!nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRx, NULL)) {
if (pnd->iLastError == EINVRXFRAM) {
// "Invalid received frame" AKA EINVRXFRAM, usual means we are
int res;
if ((res = nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRx, -1)) < 0) {
if (res == NFC_ERFTRANS) {
// "Invalid received frame", usual means we are
// authenticated on a sector but the requested MIFARE cmd (read, write)
// is not permitted by current acces bytes;
// So there is nothing to do here.
} else {
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;
}
if (!nfc_configure (pnd, NDO_EASY_FRAMING, bEasyFraming)) {
nfc_perror (pnd, "nfc_configure");
/* XXX
if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming) < 0) {
nfc_perror (pnd, "nfc_device_set_property_bool");
return false;
}
*/
// When we have executed a read command, copy the received bytes into the param
if (mc == MC_READ) {

View file

@ -38,7 +38,7 @@
# 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)
typedef enum {
@ -53,50 +53,50 @@ typedef enum {
} mifare_cmd;
// MIFARE command params
typedef struct {
byte_t abtKey[6];
byte_t abtUid[4];
} mifare_param_auth;
struct mifare_param_auth {
uint8_t abtKey[6];
uint8_t abtUid[4];
};
typedef struct {
byte_t abtData[16];
} mifare_param_data;
struct mifare_param_data {
uint8_t abtData[16];
};
typedef struct {
byte_t abtValue[4];
} mifare_param_value;
struct mifare_param_value {
uint8_t abtValue[4];
};
typedef union {
mifare_param_auth mpa;
mifare_param_data mpd;
mifare_param_value mpv;
struct mifare_param_auth mpa;
struct mifare_param_data mpd;
struct mifare_param_value mpv;
} mifare_param;
// Reset struct alignment to default
# pragma pack()
bool nfc_initiator_mifare_cmd (nfc_device_t * pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param * pmp);
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)
// MIFARE Classic
typedef struct {
byte_t abtUID[4];
byte_t btBCC;
byte_t btUnknown;
byte_t abtATQA[2];
byte_t abtUnknown[8];
uint8_t abtUID[4];
uint8_t btBCC;
uint8_t btUnknown;
uint8_t abtATQA[2];
uint8_t abtUnknown[8];
} mifare_classic_block_manufacturer;
typedef struct {
byte_t abtData[16];
uint8_t abtData[16];
} mifare_classic_block_data;
typedef struct {
byte_t abtKeyA[6];
byte_t abtAccessBits[4];
byte_t abtKeyB[6];
uint8_t abtKeyA[6];
uint8_t abtAccessBits[4];
uint8_t abtKeyB[6];
} mifare_classic_block_trailer;
typedef union {
@ -111,17 +111,17 @@ typedef struct {
// MIFARE Ultralight
typedef struct {
byte_t sn0[3];
byte_t btBCC0;
byte_t sn1[4];
byte_t btBCC1;
byte_t internal;
byte_t lock[2];
byte_t otp[4];
uint8_t sn0[3];
uint8_t btBCC0;
uint8_t sn1[4];
uint8_t btBCC1;
uint8_t internal;
uint8_t lock[2];
uint8_t otp[4];
} mifareul_block_manufacturer;
typedef struct {
byte_t abtData[16];
uint8_t abtData[16];
} mifareul_block_data;
typedef union {

View file

@ -68,7 +68,7 @@
#include "nfc-utils.h"
static nfc_device_t *pnd;
static nfc_device *pnd;
static bool quiet_output = false;
#define SYMBOL_PARAM_fISO14443_4_PICC 0x20
@ -113,7 +113,7 @@ uint8_t nfcforum_capability_container[] = {
#define ISO144434A_RATS 0xE0
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;
@ -289,7 +289,7 @@ usage (char *progname)
int
main (int argc, char *argv[])
{
nfc_target_t nt = {
nfc_target nt = {
.nm = {
.nmt = NMT_ISO14443A,
.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]);
}
}
nfc_init (NULL);
// Try to open the NFC reader
pnd = nfc_connect (NULL);
pnd = nfc_open (NULL, NULL);
if (pnd == NULL) {
ERR("Unable to connect to NFC device");
ERR("Unable to open NFC device");
exit (EXIT_FAILURE);
}
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");
if (0 != nfc_emulate_target (pnd, &emulator)) { // contains already nfc_target_init() call
nfc_perror (pnd, "nfc_emulate_target");
}
nfc_disconnect(pnd);
nfc_close(pnd);
if (argc == 3) {
if (!(ndef_message_save (argv[2], &nfcforum_tag4_data))) {
err (EXIT_FAILURE, "Can't save NDEF file '%s'", argv[2]);
}
}
nfc_exit (NULL);
exit (EXIT_SUCCESS);
}

View file

@ -18,7 +18,7 @@ This tool displays all available information at selection time.
.SH OPTIONS
.TP
.B \-v, \-\-verbose
.B \-v
Tells
.I
nfc-list

View file

@ -57,23 +57,38 @@
#define MAX_DEVICE_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
main (int argc, const char *argv[])
{
(void) argc;
const char *acLibnfcVersion;
size_t szDeviceFound;
size_t szTargetFound;
size_t i;
bool verbose = false;
nfc_device_desc_t *pnddDevices;
int res = 0;
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);
}
}
pnddDevices = parse_args (argc, argv, &szDeviceFound, &verbose);
#ifdef HAVE_LIBUSB
# ifdef DEBUG
usb_set_debug (4);
@ -82,7 +97,7 @@ main (int argc, const char *argv[])
/* Lazy way to open an NFC device */
#if 0
pnd = nfc_connect (NULL);
pnd = nfc_open (NULL, NULL);
#endif
/* 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.pcPort = "/dev/ttyUSB0";
ndd.uiSpeed = 115200;
pnd = nfc_connect (&ndd);
pnd = nfc_open (NULL, &ndd);
#endif
/* 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;
ndd.pcDriver = "PN533_USB";
strcpy(ndd.acDevice, "SCM Micro / SCL3711-NFC&RW");
pnd = nfc_connect (&ndd);
pnd = nfc_open (NULL, &ndd);
#endif
if (szDeviceFound == 0) {
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
fprintf (stderr, "malloc() failed\n");
return EXIT_FAILURE;
}
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szDeviceFound);
}
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");
}
for (i = 0; i < szDeviceFound; i++) {
nfc_target_t ant[MAX_TARGET_COUNT];
pnd = nfc_connect (&(pnddDevices[i]));
nfc_target ant[MAX_TARGET_COUNT];
pnd = nfc_open (NULL, connstrings[i]);
if (pnd == NULL) {
ERR ("%s", "Unable to connect to NFC device.");
ERR ("%s", "Unable to open NFC device.");
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.nbr = NBR_106;
// List ISO14443A targets
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n;
if (verbose || (szTargetFound > 0)) {
printf ("%d ISO14443A passive target(s) found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
int n;
if (verbose) {
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);
printf ("\n");
}
@ -146,26 +157,24 @@ main (int argc, const char *argv[])
nm.nmt = NMT_FELICA;
nm.nbr = NBR_212;
// List Felica tags
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n;
if (verbose || (szTargetFound > 0)) {
printf ("%d Felica (212 kbps) passive target(s) found%s\n", (int) szTargetFound,
(szTargetFound == 0) ? ".\n" : ":");
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
int n;
if (verbose) {
printf ("%d Felica (212 kbps) passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
}
for (n = 0; n < szTargetFound; n++) {
for (n = 0; n < res; n++) {
print_nfc_felica_info (ant[n].nti.nfi, verbose);
printf ("\n");
}
}
nm.nbr = NBR_424;
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n;
if (verbose || (szTargetFound > 0)) {
printf ("%d Felica (424 kbps) passive target(s) found%s\n", (int) szTargetFound,
(szTargetFound == 0) ? ".\n" : ":");
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
int n;
if (verbose) {
printf ("%d Felica (424 kbps) passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
}
for (n = 0; n < szTargetFound; n++) {
for (n = 0; n < res; n++) {
print_nfc_felica_info (ant[n].nti.nfi, verbose);
printf ("\n");
}
@ -174,12 +183,12 @@ main (int argc, const char *argv[])
nm.nmt = NMT_ISO14443B;
nm.nbr = NBR_106;
// List ISO14443B targets
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n;
if (verbose || (szTargetFound > 0)) {
printf ("%d ISO14443B passive target(s) found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
int n;
if (verbose) {
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);
printf ("\n");
}
@ -188,12 +197,12 @@ main (int argc, const char *argv[])
nm.nmt = NMT_ISO14443BI;
nm.nbr = NBR_106;
// List ISO14443B' targets
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n;
if (verbose || (szTargetFound > 0)) {
printf ("%d ISO14443B' passive target(s) found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
int n;
if (verbose) {
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);
printf ("\n");
}
@ -202,12 +211,12 @@ main (int argc, const char *argv[])
nm.nmt = NMT_ISO14443B2SR;
nm.nbr = NBR_106;
// List ISO14443B-2 ST SRx family targets
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n;
if (verbose || (szTargetFound > 0)) {
printf ("%d ISO14443B-2 ST SRx passive target(s) found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
int n;
if (verbose) {
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);
printf ("\n");
}
@ -216,12 +225,12 @@ main (int argc, const char *argv[])
nm.nmt = NMT_ISO14443B2CT;
nm.nbr = NBR_106;
// List ISO14443B-2 ASK CTx family targets
if (nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound)) {
size_t n;
if (verbose || (szTargetFound > 0)) {
printf ("%d ISO14443B-2 ASK CTx passive target(s) found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
if ((res = nfc_initiator_list_passive_targets (pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
int n;
if (verbose) {
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);
printf ("\n");
}
@ -230,19 +239,19 @@ main (int argc, const char *argv[])
nm.nmt = NMT_JEWEL;
nm.nbr = NBR_106;
// List Jewel targets
if (nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT, &szTargetFound )) {
size_t n;
if (verbose || (szTargetFound > 0)) {
printf("%d Jewel passive target(s) found%s\n", (int)szTargetFound, (szTargetFound==0)?".\n":":");
if ((res = nfc_initiator_list_passive_targets(pnd, nm, ant, MAX_TARGET_COUNT)) >= 0) {
int n;
if (verbose) {
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);
printf("\n");
}
}
nfc_disconnect (pnd);
nfc_close (pnd);
}
free (pnddDevices);
nfc_exit (NULL);
return 0;
}

View file

@ -52,15 +52,15 @@
#include "mifare.h"
#include "nfc-utils.h"
static nfc_device_t *pnd;
static nfc_target_t nt;
static nfc_device *pnd;
static nfc_target nt;
static mifare_param mp;
static mifare_classic_tag mtKeys;
static mifare_classic_tag mtDump;
static bool bUseKeyA;
static bool bUseKeyFile;
static uint8_t uiBlocks;
static byte_t keys[] = {
static uint8_t keys[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5,
@ -72,7 +72,7 @@ static byte_t keys[] = {
0xab, 0xcd, 0xef, 0x12, 0x34, 0x56
};
static const nfc_modulation_t nmMifare = {
static const nfc_modulation nmMifare = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
@ -81,24 +81,24 @@ static size_t num_keys = sizeof (keys) / 6;
#define MAX_FRAME_LEN 264
static byte_t abtRx[MAX_FRAME_LEN];
static size_t szRxBits;
static uint8_t abtRx[MAX_FRAME_LEN];
static int szRxBits;
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
byte_t abtUnlock1[1] = { 0x40 };
byte_t abtUnlock2[1] = { 0x43 };
uint8_t abtUnlock1[1] = { 0x40 };
uint8_t abtUnlock2[1] = { 0x43 };
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
printf ("Sent bits: ");
print_hex_bits (pbtTx, szTxBits);
// 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;
// Show received answer
@ -110,13 +110,13 @@ transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
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
printf ("Sent bits: ");
print_hex (pbtTx, szTx);
// 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;
// Show received answer
@ -127,7 +127,7 @@ transmit_bytes (const byte_t * pbtTx, const size_t szTx)
}
static void
print_success_or_failure (bool bFailure, uint32_t * uiBlockCounter)
print_success_or_failure (bool bFailure, uint32_t *uiBlockCounter)
{
printf ("%c", (bFailure) ? 'x' : '.');
if (uiBlockCounter && !bFailure)
@ -219,12 +219,12 @@ unlock_card (void)
printf ("Unlocking card\n");
// 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");
exit (EXIT_FAILURE);
}
// 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");
exit (EXIT_FAILURE);
}
@ -243,13 +243,13 @@ unlock_card (void)
// reset reader
// Configure the CRC
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
nfc_perror (pnd, "nfc_configure");
if (nfc_device_set_property_bool (pnd, NP_HANDLE_CRC, true) < 0) {
nfc_perror (pnd, "nfc_device_set_property_bool");
exit (EXIT_FAILURE);
}
// Switch off raw send/receive methods
if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) {
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");
exit (EXIT_FAILURE);
}
return true;
@ -280,7 +280,7 @@ read_card (int read_unlocked)
// Show if the readout went well
if (bFailure) {
// When a failure occured we need to redo the anti-collision
if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
if (nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt) < 0) {
printf ("!\nError: tag was removed\n");
return false;
}
@ -353,7 +353,7 @@ write_card (int write_block_zero)
// Show if the readout went well
if (bFailure) {
// When a failure occured we need to redo the anti-collision
if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
if (nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt) < 0) {
printf ("!\nError: tag was removed\n");
return false;
}
@ -458,7 +458,7 @@ int
main (int argc, const char *argv[])
{
action_t atAction = ACTION_USAGE;
byte_t *pbtUID;
uint8_t *pbtUID;
FILE *pfKeys = NULL;
FILE *pfDump = NULL;
int unlock= 0;
@ -537,29 +537,35 @@ main (int argc, const char *argv[])
}
// printf("Successfully opened required files\n");
nfc_init (NULL);
// Try to open the NFC reader
pnd = nfc_connect (NULL);
pnd = nfc_open (NULL, NULL);
if (pnd == NULL) {
printf ("Error connecting NFC reader\n");
printf ("Error opening NFC reader\n");
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
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
nfc_perror (pnd, "nfc_configure");
if (nfc_device_set_property_bool (pnd, NP_INFINITE_SELECT, false) < 0) {
nfc_perror (pnd, "nfc_device_set_property_bool");
exit (EXIT_FAILURE);
}
// Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance.
nfc_configure (pnd, NDO_AUTO_ISO14443_4, false);
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
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");
nfc_disconnect (pnd);
nfc_close (pnd);
nfc_exit (NULL);
exit (EXIT_FAILURE);
}
// 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;
if (bUseKeyFile) {
byte_t fileUid[4];
uint8_t fileUid[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
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",
fileUid[0], fileUid[1], fileUid[2], fileUid[3]);
}
@ -615,7 +621,7 @@ main (int argc, const char *argv[])
write_card (unlock);
}
nfc_disconnect (pnd);
nfc_close (pnd);
break;
case ACTION_EXTRACT:{
@ -658,6 +664,7 @@ main (int argc, const char *argv[])
printf ("Done, all bytes have been extracted!\n");
}
};
nfc_exit (NULL);
exit (EXIT_SUCCESS);
}

View file

@ -56,39 +56,39 @@
#define MAX_FRAME_LEN 264
static byte_t abtRx[MAX_FRAME_LEN];
static size_t szRxBits;
static uint8_t abtRx[MAX_FRAME_LEN];
static int szRxBits;
static size_t szRx = sizeof(abtRx);
static byte_t abtRawUid[12];
static byte_t abtAtqa[2];
static byte_t abtSak;
static byte_t abtAts[MAX_FRAME_LEN];
static byte_t szAts = 0;
static uint8_t abtRawUid[12];
static uint8_t abtAtqa[2];
static uint8_t abtSak;
static uint8_t abtAts[MAX_FRAME_LEN];
static uint8_t szAts = 0;
static size_t szCL = 1;//Always start with Cascade Level 1 (CL1)
static nfc_device_t *pnd;
static nfc_device *pnd;
bool quiet_output = false;
bool iso_ats_supported = false;
// ISO14443A Anti-Collision Commands
byte_t abtReqa[1] = { 0x26 };
byte_t abtSelectAll[2] = { 0x93, 0x20 };
byte_t abtSelectTag[9] = { 0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
byte_t abtRats[4] = { 0xe0, 0x50, 0x00, 0x00 };
byte_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
uint8_t abtReqa[1] = { 0x26 };
uint8_t abtSelectAll[2] = { 0x93, 0x20 };
uint8_t abtSelectTag[9] = { 0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t abtRats[4] = { 0xe0, 0x50, 0x00, 0x00 };
uint8_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
#define CASCADE_BIT 0x04
// special unlock command
byte_t abtUnlock1[1] = { 0x40 };
byte_t abtUnlock2[1] = { 0x43 };
byte_t abtWipe[1] = { 0x41 };
byte_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 };
byte_t abtBlank[18] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x36, 0xCC };
uint8_t abtUnlock1[1] = { 0x40 };
uint8_t abtUnlock2[1] = { 0x43 };
uint8_t abtWipe[1] = { 0x41 };
uint8_t abtWrite[4] = { 0xa0, 0x00, 0x5f, 0xb1 };
uint8_t abtData[18] = { 0x01, 0x23, 0x45, 0x67, 0x00, 0x08, 0x04, 0x00, 0x46, 0x59, 0x25, 0x58, 0x49, 0x10, 0x23, 0x02, 0x23, 0xeb };
uint8_t abtBlank[18] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x36, 0xCC };
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
if (!quiet_output) {
@ -96,7 +96,7 @@ transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
print_hex_bits (pbtTx, szTxBits);
}
// 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;
// Show received answer
@ -110,7 +110,7 @@ transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
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
if (!quiet_output) {
@ -118,7 +118,7 @@ transmit_bytes (const byte_t * pbtTx, const size_t szTx)
print_hex (pbtTx, szTx);
}
// 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;
// Show received answer
@ -177,39 +177,45 @@ main (int argc, char *argv[])
}
}
nfc_init (NULL);
// Try to open the NFC reader
pnd = nfc_connect (NULL);
pnd = nfc_open (NULL, NULL);
if (!pnd) {
printf ("Error connecting NFC reader\n");
printf ("Error opening NFC reader\n");
exit(EXIT_FAILURE);
}
// 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
if (!nfc_configure (pnd, NDO_HANDLE_CRC, false)) {
nfc_perror (pnd, "nfc_configure");
if (nfc_device_set_property_bool (pnd, NP_HANDLE_CRC, false) < 0) {
nfc_perror (pnd, "nfc_device_set_property_bool");
exit (EXIT_FAILURE);
}
// Use raw send/receive methods
if (!nfc_configure (pnd, NDO_EASY_FRAMING, false)) {
nfc_perror (pnd, "nfc_configure");
if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, false) < 0) {
nfc_perror (pnd, "nfc_device_set_property_bool");
exit (EXIT_FAILURE);
}
// Disable 14443-4 autoswitching
if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, false)) {
nfc_perror (pnd, "nfc_configure");
if (nfc_device_set_property_bool (pnd, NP_AUTO_ISO14443_4, false) < 0) {
nfc_perror (pnd, "nfc_device_set_property_bool");
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)
if (!transmit_bits (abtReqa, 7)) {
printf ("Error: No tag available\n");
nfc_disconnect (pnd);
nfc_close (pnd);
nfc_exit (NULL);
return 1;
}
memcpy (abtAtqa, abtRx, 2);
@ -338,7 +344,7 @@ main (int argc, char *argv[])
transmit_bytes (abtWrite,4);
transmit_bytes (abtData,18);
if(format) {
for(i= 3 ; i < 64 ; i += 4) {
for(i = 3 ; i < 64 ; i += 4) {
abtWrite[1]= (char) i;
iso14443a_crc_append (abtWrite, 2);
transmit_bytes (abtWrite,4);
@ -347,6 +353,7 @@ main (int argc, char *argv[])
}
nfc_disconnect (pnd);
nfc_close (pnd);
nfc_exit (NULL);
return 0;
}

View file

@ -51,13 +51,13 @@
#include "nfc-utils.h"
#include "mifare.h"
static nfc_device_t *pnd;
static nfc_target_t nt;
static nfc_device *pnd;
static nfc_target nt;
static mifare_param mp;
static mifareul_tag mtDump;
static uint32_t uiBlocks = 0xF;
static const nfc_modulation_t nmMifare = {
static const nfc_modulation nmMifare = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
};
@ -142,7 +142,7 @@ write_card (void)
// Show if the readout went well
if (bFailure) {
// When a failure occured we need to redo the anti-collision
if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
if (nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt) < 0) {
ERR ("tag was removed");
return false;
}
@ -204,34 +204,41 @@ main (int argc, const char *argv[])
}
DBG ("Successfully opened the dump file\n");
nfc_init (NULL);
// Try to open the NFC device
pnd = nfc_connect (NULL);
pnd = nfc_open (NULL, NULL);
if (pnd == NULL) {
ERR ("Error connecting NFC device\n");
ERR ("Error opening NFC device\n");
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
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
nfc_perror (pnd, "nfc_configure");
if (nfc_device_set_property_bool (pnd, NP_INFINITE_SELECT, false) < 0) {
nfc_perror (pnd, "nfc_device_set_property_bool");
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
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");
nfc_disconnect (pnd);
nfc_close (pnd);
nfc_exit (NULL);
return 1;
}
// Test if we are dealing with a MIFARE compatible tag
if (nt.nti.nai.abtAtqa[1] != 0x44) {
ERR ("tag is not a MIFARE Ultralight card\n");
nfc_disconnect (pnd);
nfc_close (pnd);
nfc_exit (NULL);
return EXIT_FAILURE;
}
// Get the info from the current tag
@ -262,7 +269,7 @@ main (int argc, const char *argv[])
write_card ();
}
nfc_disconnect (pnd);
nfc_close (pnd);
nfc_exit (NULL);
return EXIT_SUCCESS;
}

115
utils/nfc-probe.c Normal file
View 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;
}

View file

@ -56,7 +56,7 @@
#include "nfc-utils.h"
static nfc_device_t *pnd;
static nfc_device *pnd;
void
print_usage(char *progname)
@ -76,7 +76,7 @@ void stop_select (int sig)
}
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_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
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
0x0B, 0x00, // NFC Forum Tag Type 3's Service code
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;
for (uint8_t b=0; b<block_count; b++) {
for (uint8_t b = 0; b < block_count; b++) {
if (block < 0x100) {
payload[payload_len++] = 0x80;
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);
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;
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;
}
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
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
return -1;
}
const byte_t status_flag1 = res[10];
const byte_t status_flag2 = res[11];
const uint8_t status_flag1 = res[10];
const uint8_t status_flag2 = res[11];
if ((status_flag1) || (status_flag2)) {
// Felica card's error
fprintf (stderr, "Status bytes: %02x, %02x\n", status_flag1, status_flag2);
@ -193,43 +193,48 @@ main(int argc, char *argv[])
exit (EXIT_FAILURE);
}
}
nfc_init (NULL);
pnd = nfc_connect (NULL);
pnd = nfc_open (NULL, NULL);
if (pnd == NULL) {
ERR("Unable to connect to NFC device");
ERR("Unable to open NFC device");
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,
.nbr = NBR_212,
};
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");
int error = EXIT_SUCCESS;
// Polling payload (SENSF_REQ) must be present (see NFC Digital Protol)
const byte_t *pbtSensfReq = (byte_t*)"\x00\xff\xff\x01\x00";
if (!nfc_initiator_select_passive_target(pnd, nm, pbtSensfReq, 5, &nt)) {
const uint8_t *pbtSensfReq = (uint8_t*)"\x00\xff\xff\x01\x00";
if (nfc_initiator_select_passive_target(pnd, nm, pbtSensfReq, 5, &nt) < 0) {
nfc_perror (pnd, "nfc_initiator_select_passive_target");
error = EXIT_FAILURE;
goto error;
}
// 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)) {
// Retry with special polling
const byte_t *pbtSensfReqNfcForum = (byte_t*)"\x00\x12\xfc\x01\x00";
if (!nfc_initiator_select_passive_target(pnd, nm, pbtSensfReqNfcForum, 5, &nt)) {
const uint8_t *pbtSensfReqNfcForum = (uint8_t*)"\x00\x12\xfc\x01\x00";
if (nfc_initiator_select_passive_target(pnd, nm, pbtSensfReqNfcForum, 5, &nt) < 0) {
nfc_perror (pnd, "nfc_initiator_select_passive_target");
error = EXIT_FAILURE;
goto error;
@ -244,13 +249,13 @@ main(int argc, char *argv[])
//print_nfc_felica_info(nt.nti.nfi, true);
if (!nfc_configure (pnd, NDO_EASY_FRAMING, false) || !nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
nfc_perror (pnd, "nfc_configure");
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_device_set_property_bool");
error = EXIT_FAILURE;
goto error;
}
byte_t data[1024];
uint8_t data[1024];
size_t data_len = sizeof(data);
int len;
@ -271,7 +276,7 @@ main(int argc, char *argv[])
fprintf (message_stream, "NDEF data lenght: %d bytes\n", ndef_data_len);
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];
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;
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;
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");
@ -309,7 +314,8 @@ main(int argc, char *argv[])
error:
fclose (ndef_stream);
if (pnd) {
nfc_disconnect (pnd);
nfc_close (pnd);
}
nfc_exit (NULL);
exit (error);
}

View file

@ -57,12 +57,12 @@
#define MAX_FRAME_LEN 264
#define MAX_DEVICE_COUNT 2
static byte_t abtCapdu[MAX_FRAME_LEN];
static uint8_t abtCapdu[MAX_FRAME_LEN];
static size_t szCapduLen;
static byte_t abtRapdu[MAX_FRAME_LEN];
static uint8_t abtRapdu[MAX_FRAME_LEN];
static size_t szRapduLen;
static nfc_device_t *pndInitiator;
static nfc_device_t *pndTarget;
static nfc_device *pndInitiator;
static nfc_device *pndTarget;
static bool quitting = false;
static bool quiet_output = 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");
}
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;
if (szBytes > MAX_FRAME_LEN) {
return EXIT_FAILURE;
}
if (fprintf (fd4, "#%s %04zx: ", pchPrefix, szBytes)<0) {
if (fprintf (fd4, "#%s %04zx: ", pchPrefix, szBytes) < 0) {
return EXIT_FAILURE;
}
for (szPos = 0; szPos < szBytes; szPos++) {
if (fprintf (fd4, "%02x ", pbtData[szPos])<0) {
if (fprintf (fd4, "%02x ", pbtData[szPos]) < 0) {
return EXIT_FAILURE;
}
}
if (fprintf (fd4, "\n")<0) {
if (fprintf (fd4, "\n") < 0) {
return EXIT_FAILURE;
}
fflush(fd4);
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;
unsigned int uiBytes;
@ -129,7 +129,7 @@ bool scan_hex_fd3 (byte_t *pbtData, size_t *pszBytes, const char * pchPrefix)
}
strncpy(pchScan, pchPrefix, 250);
strcat(pchScan, " %04x:");
if (fscanf (fd3, pchScan, &uiBytes)<1) {
if (fscanf (fd3, pchScan, &uiBytes) < 1) {
return EXIT_FAILURE;
}
*pszBytes=uiBytes;
@ -137,7 +137,7 @@ bool scan_hex_fd3 (byte_t *pbtData, size_t *pszBytes, const char * pchPrefix)
return EXIT_FAILURE;
}
for (szPos = 0; szPos < *pszBytes; szPos++) {
if (fscanf (fd3, "%02x", &uiData)<1) {
if (fscanf (fd3, "%02x", &uiData) < 1) {
return EXIT_FAILURE;
}
pbtData[szPos]=uiData;
@ -149,10 +149,8 @@ int
main (int argc, char *argv[])
{
int arg;
size_t szFound;
nfc_device_desc_t *pnddDevices;
const char *acLibnfcVersion = nfc_version ();
nfc_target_t ntRealTarget;
nfc_target ntRealTarget;
// Get commandline options
for (arg = 1; arg < argc; arg++) {
@ -170,7 +168,7 @@ main (int argc, char *argv[])
initiator_only_mode = true;
target_only_mode = false;
} 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]);
print_usage (argv);
return EXIT_FAILURE;
@ -192,13 +190,11 @@ main (int argc, char *argv[])
signal (SIGINT, (void (*)()) intr_hdlr);
#endif
// Allocate memory to put the result of available devices listing
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
fprintf (stderr, "malloc() failed\n");
return EXIT_FAILURE;
}
nfc_init (NULL);
nfc_connstring connstrings[MAX_DEVICE_COUNT];
// 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 (szFound < 1) {
@ -210,7 +206,7 @@ main (int argc, char *argv[])
}
else {
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;
}
}
@ -219,35 +215,37 @@ main (int argc, char *argv[])
// Try to open the NFC reader used as initiator
// Little hack to allow using initiator no matter if
// 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)
if (szFound == 1) {
pndInitiator = nfc_connect (&(pnddDevices[0]));
pndInitiator = nfc_open (NULL, connstrings[0]);
} else {
pndInitiator = nfc_connect (&(pnddDevices[1]));
pndInitiator = nfc_open (NULL, connstrings[1]);
}
if (!pndInitiator) {
printf ("Error connecting NFC reader\n");
printf ("Error opening NFC reader\n");
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");
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
nfc_exit (NULL);
exit (EXIT_FAILURE);
}
// Try to find a ISO 14443-4A tag
nfc_modulation_t nm = {
nfc_modulation nm = {
.nmt = NMT_ISO14443A,
.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");
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
nfc_exit (NULL);
exit (EXIT_FAILURE);
}
@ -256,22 +254,26 @@ main (int argc, char *argv[])
if (initiator_only_mode) {
if (print_hex_fd4(ntRealTarget.nti.nai.abtUid, ntRealTarget.nti.nai.szUidLen, "UID") != EXIT_SUCCESS) {
fprintf (stderr, "Error while printing UID to FD4\n");
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
if (print_hex_fd4(ntRealTarget.nti.nai.abtAtqa, 2, "ATQA") != EXIT_SUCCESS) {
fprintf (stderr, "Error while printing ATQA to FD4\n");
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
if (print_hex_fd4(&(ntRealTarget.nti.nai.btSak), 1, "SAK") != EXIT_SUCCESS) {
fprintf (stderr, "Error while printing SAK to FD4\n");
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
if (print_hex_fd4(ntRealTarget.nti.nai.abtAts, ntRealTarget.nti.nai.szAtsLen, "ATS") != EXIT_SUCCESS) {
fprintf (stderr, "Error while printing ATS to FD4\n");
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
}
@ -284,7 +286,7 @@ main (int argc, char *argv[])
printf ("Hint: tag <---> initiator (relay) <---> target (relay) <---> original reader\n\n");
}
if (!initiator_only_mode) {
nfc_target_t ntEmulatedTarget = {
nfc_target ntEmulatedTarget = {
.nm = {
.nmt = NMT_ISO14443A,
.nbr = NBR_106,
@ -294,22 +296,25 @@ main (int argc, char *argv[])
size_t foo;
if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtUid, &(ntEmulatedTarget.nti.nai.szUidLen), "UID") != EXIT_SUCCESS) {
fprintf (stderr, "Error while scanning UID from FD3\n");
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAtqa, &foo, "ATQA") != EXIT_SUCCESS) {
fprintf (stderr, "Error while scanning ATQA from FD3\n");
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
exit(EXIT_FAILURE);
}
if (scan_hex_fd3(&(ntEmulatedTarget.nti.nai.btSak), &foo, "SAK") != EXIT_SUCCESS) {
fprintf (stderr, "Error while scanning SAK from FD3\n");
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAts, &(ntEmulatedTarget.nti.nai.szAtsLen), "ATS") != EXIT_SUCCESS) {
fprintf (stderr, "Error while scanning ATS from FD3\n");
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
} 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
// Creates ATS and copy max 48 bytes of Tk:
byte_t * pbtTk;
uint8_t * pbtTk;
size_t szTk;
pbtTk = iso14443a_locate_historical_bytes (ntEmulatedTarget.nti.nai.abtAts, ntEmulatedTarget.nti.nai.szAtsLen, &szTk);
szTk = (szTk > 48) ? 48 : szTk;
byte_t pbtTkt[48];
uint8_t pbtTkt[48];
memcpy(pbtTkt, pbtTk, szTk);
ntEmulatedTarget.nti.nai.abtAts[0] = 0x75;
ntEmulatedTarget.nti.nai.abtAts[1] = 0x33;
@ -348,23 +353,26 @@ main (int argc, char *argv[])
print_nfc_iso14443a_info (ntEmulatedTarget.nti.nai, false);
// Try to open the NFC emulator device
pndTarget = nfc_connect (&(pnddDevices[0]));
pndTarget = nfc_open (NULL, connstrings[0]);
if (pndTarget == NULL) {
printf ("Error connecting NFC emulator device\n");
printf ("Error opening NFC emulator device\n");
if (!target_only_mode) {
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
}
nfc_exit (NULL);
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");
if (!target_only_mode) {
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
}
nfc_disconnect (pndTarget);
nfc_close (pndTarget);
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
printf ("%s\n", "Done, relaying frames now!");
@ -373,27 +381,32 @@ main (int argc, char *argv[])
while (!quitting) {
bool ret;
int res = 0;
if (!initiator_only_mode) {
// 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");
if (!target_only_mode) {
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
}
nfc_disconnect (pndTarget);
nfc_close (pndTarget);
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
szCapduLen = (size_t) res;
if (target_only_mode) {
if (print_hex_fd4(abtCapdu, szCapduLen, "C-APDU") != EXIT_SUCCESS) {
fprintf (stderr, "Error while printing C-APDU to FD4\n");
nfc_disconnect (pndTarget);
nfc_close (pndTarget);
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
}
} else {
if (scan_hex_fd3(abtCapdu, &szCapduLen, "C-APDU") != EXIT_SUCCESS) {
fprintf (stderr, "Error while scanning C-APDU from FD3\n");
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
}
@ -405,12 +418,13 @@ main (int argc, char *argv[])
if (!target_only_mode) {
// Forward the frame to the original tag
ret = nfc_initiator_transceive_bytes
(pndInitiator, abtCapdu, szCapduLen, abtRapdu, &szRapduLen, NULL);
ret = (nfc_initiator_transceive_bytes
(pndInitiator, abtCapdu, szCapduLen, abtRapdu, &szRapduLen, 0) < 0) ? 0 : 1;
} else {
if (scan_hex_fd3(abtRapdu, &szRapduLen, "R-APDU") != EXIT_SUCCESS) {
fprintf (stderr, "Error while scanning R-APDU from FD3\n");
nfc_disconnect (pndTarget);
nfc_close (pndTarget);
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
ret = true;
@ -430,20 +444,23 @@ main (int argc, char *argv[])
}
if (!initiator_only_mode) {
// 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");
if (!target_only_mode) {
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
}
if (!initiator_only_mode) {
nfc_disconnect (pndTarget);
nfc_close (pndTarget);
nfc_exit (NULL);
}
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
} else {
if (print_hex_fd4(abtRapdu, szRapduLen, "R-APDU") != EXIT_SUCCESS) {
fprintf (stderr, "Error while printing R-APDU to FD4\n");
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
nfc_exit (NULL);
exit(EXIT_FAILURE);
}
}
@ -451,11 +468,12 @@ main (int argc, char *argv[])
}
if (!target_only_mode) {
nfc_disconnect (pndInitiator);
nfc_close (pndInitiator);
}
if (!initiator_only_mode) {
nfc_disconnect (pndTarget);
nfc_close (pndTarget);
}
nfc_exit (NULL);
exit (EXIT_SUCCESS);
}

View file

@ -33,7 +33,7 @@
#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,
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
};
byte_t
oddparity (const byte_t bt)
uint8_t
oddparity (const uint8_t bt)
{
return OddParity[bt];
}
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;
// 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
print_hex (const byte_t * pbtData, const size_t szBytes)
print_hex (const uint8_t *pbtData, const size_t szBytes)
{
size_t szPos;
@ -80,7 +80,7 @@ print_hex (const byte_t * pbtData, const size_t szBytes)
}
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;
size_t szPos;
@ -102,7 +102,7 @@ print_hex_bits (const byte_t * pbtData, const size_t szBits)
}
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;
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
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): ");
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;
if (nai.abtAts[0] & 0x10) { // TA(1) present
byte_t TA = nai.abtAts[offset];
uint8_t TA = nai.abtAts[offset];
offset++;
printf ("* Bit Rate Capability:\n");
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
byte_t TB= nai.abtAts[offset];
uint8_t TB= nai.abtAts[offset];
offset++;
printf ("* Frame Waiting Time: %.4g ms\n",256.0*16.0*(1<<((TB & 0xf0) >> 4))/13560.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
byte_t TC = nai.abtAts[offset];
uint8_t TC = nai.abtAts[offset];
offset++;
if (TC & 0x1) {
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) {
printf ("* Historical bytes Tk: " );
print_hex (nai.abtAts + offset, (nai.szAtsLen - offset));
byte_t CIB = nai.abtAts[offset];
uint8_t CIB = nai.abtAts[offset];
offset++;
if (CIB != 0x00 && CIB != 0x10 && (CIB & 0xf0) != 0x80) {
printf(" * Proprietary format\n");
if (CIB == 0xc1) {
printf(" * Tag byte: Mifare or virtual cards of various types\n");
byte_t L = nai.abtAts[offset];
uint8_t L = nai.abtAts[offset];
offset++;
if (L != (nai.szAtsLen - offset)) {
printf(" * Warning: Type Identification Coding length (%i)", L);
printf(" not matching Tk length (%zi)\n", (nai.szAtsLen - offset));
}
if ((nai.szAtsLen - offset - 2) > 0) { // Omit 2 CRC bytes
byte_t CTC = nai.abtAts[offset];
uint8_t CTC = nai.abtAts[offset];
offset++;
printf(" * Chip Type: ");
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
byte_t CVC = nai.abtAts[offset];
uint8_t CVC = nai.abtAts[offset];
offset++;
printf(" * Chip Status: ");
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
byte_t VCS = nai.abtAts[offset];
uint8_t VCS = nai.abtAts[offset];
offset++;
printf(" * Specifics (Virtual Card Selection):\n");
if ((VCS & 0x09) == 0x00) {
@ -530,7 +530,7 @@ print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose)
}
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;
printf (" ID (NFCID2): ");
@ -542,7 +542,7 @@ print_nfc_felica_info (const nfc_felica_info_t nfi, bool verbose)
}
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;
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_CID_SUPPORTED 0x02
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 };
printf (" PUPI: ");
@ -610,7 +610,7 @@ print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi, bool verbose)
}
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: ");
print_hex (nii.abtDIV, 4);
@ -634,7 +634,7 @@ print_nfc_iso14443bi_info (const nfc_iso14443bi_info_t nii, bool verbose)
}
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;
printf (" UID: ");
@ -642,7 +642,7 @@ print_nfc_iso14443b2sr_info (const nfc_iso14443b2sr_info_t nsi, bool verbose)
}
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;
uint32_t uid;
@ -655,7 +655,7 @@ print_nfc_iso14443b2ct_info (const nfc_iso14443b2ct_info_t nci, bool verbose)
}
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;
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 *
str_nfc_baud_rate (const nfc_baud_rate_t nbr)
str_nfc_baud_rate (const nfc_baud_rate nbr)
{
switch(nbr) {
case NBR_UNDEFINED:
@ -739,7 +694,7 @@ str_nfc_baud_rate (const nfc_baud_rate_t nbr)
}
void
print_nfc_target (const nfc_target_t nt, bool verbose)
print_nfc_target (const nfc_target nt, bool verbose)
{
switch(nt.nm.nmt) {
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);
break;
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);
break;
}

View file

@ -79,24 +79,23 @@
# define ERR(...) warnx ("ERROR: " __VA_ARGS__ )
#endif
byte_t oddparity (const byte_t bt);
void oddparity_byte_ts (const byte_t * pbtData, const size_t szLen, byte_t * pbtPar);
uint8_t oddparity (const uint8_t bt);
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_bits (const byte_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 (const uint8_t *pbtData, const size_t szLen);
void print_hex_bits (const uint8_t *pbtData, const size_t szBits);
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_iso14443b_info (const nfc_iso14443b_info_t nbi, bool verbose);
void print_nfc_iso14443bi_info (const nfc_iso14443bi_info_t nii, bool verbose);
void print_nfc_iso14443b2sr_info (const nfc_iso14443b2sr_info_t nsi, bool verbose);
void print_nfc_iso14443b2ct_info (const nfc_iso14443b2ct_info_t nci, bool verbose);
void print_nfc_felica_info (const nfc_felica_info_t nfi, bool verbose);
void print_nfc_jewel_info (const nfc_jewel_info_t nji, bool verbose);
void print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose);
void print_nfc_iso14443a_info (const nfc_iso14443a_info nai, bool verbose);
void print_nfc_iso14443b_info (const nfc_iso14443b_info nbi, bool verbose);
void print_nfc_iso14443bi_info (const nfc_iso14443bi_info nii, bool verbose);
void print_nfc_iso14443b2sr_info (const nfc_iso14443b2sr_info nsi, bool verbose);
void print_nfc_iso14443b2ct_info (const nfc_iso14443b2ct_info nci, bool verbose);
void print_nfc_felica_info (const nfc_felica_info nfi, bool verbose);
void print_nfc_jewel_info (const nfc_jewel_info nji, 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);
nfc_device_desc_t *parse_args (int argc, const char *argv[], size_t * szFound, bool * verbose);
void print_nfc_target (const nfc_target nt, bool verbose);
#endif