diff --git a/Makefile.am b/Makefile.am index 0d595db..273cc52 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/configure.ac b/configure.ac index d561d45..dd71f22 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/contrib/Makefile.am b/contrib/Makefile.am index ed130fa..92701a4 100644 --- a/contrib/Makefile.am +++ b/contrib/Makefile.am @@ -1,4 +1,7 @@ -SUBDIRS = win32 +SUBDIRS = \ + devd \ + udev \ + win32 EXTRA_DIST = \ windows.h diff --git a/contrib/devd/Makefile.am b/contrib/devd/Makefile.am new file mode 100644 index 0000000..c846575 --- /dev/null +++ b/contrib/devd/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = \ + pn53x.conf diff --git a/pn53x.conf b/contrib/devd/pn53x.conf similarity index 100% rename from pn53x.conf rename to contrib/devd/pn53x.conf diff --git a/pn53x.rules b/contrib/udev/42-pn53x.rules similarity index 100% rename from pn53x.rules rename to contrib/udev/42-pn53x.rules diff --git a/contrib/udev/Makefile.am b/contrib/udev/Makefile.am new file mode 100644 index 0000000..86655ae --- /dev/null +++ b/contrib/udev/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = \ + 42-pn53x.rules diff --git a/debian/changelog b/debian/changelog index b94b163..91b4f01 100644 --- a/debian/changelog +++ b/debian/changelog @@ -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 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 diff --git a/debian/libnfc2.install b/debian/libnfc2.install index c944438..08cb976 100644 --- a/debian/libnfc2.install +++ b/debian/libnfc2.install @@ -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/ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f4571d1..d3fd23b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -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) diff --git a/examples/Makefile.am b/examples/Makefile.am index 627ed4d..e0a93ff 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -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 diff --git a/examples/doc/quick_start_example1.c b/examples/doc/quick_start_example1.c index 46abd0c..9c405aa 100644 --- a/examples/doc/quick_start_example1.c +++ b/examples/doc/quick_start_example1.c @@ -5,45 +5,42 @@ #include #include -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; } diff --git a/examples/nfc-anticol.c b/examples/nfc-anticol.c index a1f906f..87aa1c4 100644 --- a/examples/nfc-anticol.c +++ b/examples/nfc-anticol.c @@ -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; } diff --git a/examples/nfc-dep-initiator.c b/examples/nfc-dep-initiator.c index db8ac9a..272cdf0 100644 --- a/examples/nfc-dep-initiator.c +++ b/examples/nfc-dep-initiator.c @@ -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; } diff --git a/examples/nfc-dep-target.c b/examples/nfc-dep-target.c index d902c56..9786ead 100644 --- a/examples/nfc-dep-target.c +++ b/examples/nfc-dep-target.c @@ -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; } diff --git a/utils/nfc-emulate-forum-tag2.c b/examples/nfc-emulate-forum-tag2.c similarity index 91% rename from utils/nfc-emulate-forum-tag2.c rename to examples/nfc-emulate-forum-tag2.c index 0159bae..c636c7d 100644 --- a/utils/nfc-emulate-forum-tag2.c +++ b/examples/nfc-emulate-forum-tag2.c @@ -69,9 +69,9 @@ #include #include -#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); } } diff --git a/examples/nfc-emulate-tag.c b/examples/nfc-emulate-tag.c index 79792c8..7e236fe 100644 --- a/examples/nfc-emulate-tag.c +++ b/examples/nfc-emulate-tag.c @@ -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); } diff --git a/examples/nfc-emulate-uid.c b/examples/nfc-emulate-uid.c index 4548dc8..cfa2b4f 100644 --- a/examples/nfc-emulate-uid.c +++ b/examples/nfc-emulate-uid.c @@ -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); } diff --git a/examples/nfc-poll.1 b/examples/nfc-poll.1 index 86bf93a..682c99c 100644 --- a/examples/nfc-poll.1 +++ b/examples/nfc-poll.1 @@ -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: diff --git a/examples/nfc-poll.c b/examples/nfc-poll.c index 2843654..e1873a4 100644 --- a/examples/nfc-poll.c +++ b/examples/nfc-poll.c @@ -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); } diff --git a/examples/nfc-relay.c b/examples/nfc-relay.c index 720b094..6a95c3f 100644 --- a/examples/nfc-relay.c +++ b/examples/nfc-relay.c @@ -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); } diff --git a/examples/pn53x-diagnose.c b/examples/pn53x-diagnose.c index c11a236..6743eaa 100644 --- a/examples/pn53x-diagnose.c +++ b/examples/pn53x-diagnose.c @@ -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"); diff --git a/examples/pn53x-sam.c b/examples/pn53x-sam.c index 6bbf8bc..459f5f7 100644 --- a/examples/pn53x-sam.c +++ b/examples/pn53x-sam.c @@ -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); } diff --git a/examples/pn53x-tamashell.c b/examples/pn53x-tamashell.c index 1d3fe94..aad5006 100644 --- a/examples/pn53x-tamashell.c +++ b/examples/pn53x-tamashell.c @@ -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 # include -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() diff --git a/include/nfc/nfc.h b/include/nfc/nfc.h index 051f691..8c2b1b7 100644 --- a/include/nfc/nfc.h +++ b/include/nfc/nfc.h @@ -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 } diff --git a/libnfc/Makefile.am b/libnfc/Makefile.am index f596549..7a62c23 100644 --- a/libnfc/Makefile.am +++ b/libnfc/Makefile.am @@ -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 + diff --git a/libnfc/buses/Makefile.am b/libnfc/buses/Makefile.am index f3475c4..e28ac91 100644 --- a/libnfc/buses/Makefile.am +++ b/libnfc/buses/Makefile.am @@ -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 diff --git a/libnfc/buses/uart.h b/libnfc/buses/uart.h index a2fbd96..728d998 100644 --- a/libnfc/buses/uart.h +++ b/libnfc/buses/uart.h @@ -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); diff --git a/libnfc/buses/uart_posix.c b/libnfc/buses/uart_posix.c index 78cf67b..4e41d8e 100644 --- a/libnfc/buses/uart_posix.c +++ b/libnfc/buses/uart_posix.c @@ -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 ** diff --git a/libnfc/buses/uart_win32.c b/libnfc/buses/uart_win32.c index 29977c6..8ae25ef 100644 --- a/libnfc/buses/uart_win32.c +++ b/libnfc/buses/uart_win32.c @@ -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++) { diff --git a/libnfc/chips/Makefile.am b/libnfc/chips/Makefile.am index a8ad491..2359e78 100644 --- a/libnfc/chips/Makefile.am +++ b/libnfc/chips/Makefile.am @@ -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 - diff --git a/libnfc/chips/pn53x-internal.h b/libnfc/chips/pn53x-internal.h index b133d38..7861091 100644 --- a/libnfc/chips/pn53x-internal.h +++ b/libnfc/chips/pn53x-internal.h @@ -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[] = { diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index 246d839..bdd774f 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -35,36 +35,37 @@ #include #include -#include #include +#include "nfc/nfc.h" +#include "nfc-internal.h" #include "pn53x.h" #include "pn53x-internal.h" #include "mirror-subr.h" -#include "nfc-internal.h" #define LOG_CATEGORY "libnfc.chip.pn53x" -const byte_t pn53x_ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 }; -const byte_t pn53x_nack_frame[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 }; -static const byte_t pn53x_error_frame[] = { 0x00, 0x00, 0xff, 0x01, 0xff, 0x7f, 0x81, 0x00 }; +const uint8_t pn53x_ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 }; +const uint8_t pn53x_nack_frame[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 }; +static const uint8_t pn53x_error_frame[] = { 0x00, 0x00, 0xff, 0x01, 0xff, 0x7f, 0x81, 0x00 }; /* prototypes */ -bool pn53x_reset_settings (nfc_device_t * pnd); -bool pn53x_writeback_register (nfc_device_t * pnd); +int pn53x_reset_settings (struct nfc_device *pnd); +int pn53x_writeback_register (struct nfc_device *pnd); -nfc_modulation_t pn53x_ptt_to_nm (const pn53x_target_type_t ptt); -pn53x_modulation_t pn53x_nm_to_pm (const nfc_modulation_t nm); -pn53x_target_type_t pn53x_nm_to_ptt (const nfc_modulation_t nm); +nfc_modulation pn53x_ptt_to_nm (const pn53x_target_type ptt); +pn53x_modulation pn53x_nm_to_pm (const nfc_modulation nm); +pn53x_target_type pn53x_nm_to_ptt (const nfc_modulation nm); -bool -pn53x_init(nfc_device_t * pnd) +int +pn53x_init(struct nfc_device *pnd) { + int res = 0; // GetFirmwareVersion command is used to set PN53x chips type (PN531, PN532 or PN533) char abtFirmwareText[22]; - if (!pn53x_get_firmware_version (pnd, abtFirmwareText)) { - return false; + if ((res = pn53x_get_firmware_version (pnd, abtFirmwareText)) < 0) { + return res; } // CRC handling should be enabled by default as declared in nfc_device_new @@ -74,78 +75,87 @@ pn53x_init(nfc_device_t * pnd) // We can't read these parameters, so we set a default config by using the SetParameters wrapper // Note: pn53x_SetParameters() will save the sent value in pnd->ui8Parameters cache - if(!pn53x_SetParameters(pnd, PARAM_AUTO_ATR_RES | PARAM_AUTO_RATS)) { - return false; + if((res = pn53x_SetParameters(pnd, PARAM_AUTO_ATR_RES | PARAM_AUTO_RATS)) < 0) { + return res; } - pn53x_reset_settings(pnd); + if ((res = pn53x_reset_settings(pnd)) < 0) { + return res; + } // Add the firmware revision to the device name char *pcName; - pcName = strdup (pnd->acName); - snprintf (pnd->acName, DEVICE_NAME_LENGTH - 1, "%s - %s", pcName, abtFirmwareText); + pcName = strdup (pnd->name); + snprintf (pnd->name, DEVICE_NAME_LENGTH - 1, "%s - %s", pcName, abtFirmwareText); free (pcName); - return true; + return NFC_SUCCESS; } -bool -pn53x_reset_settings(nfc_device_t * pnd) +int +pn53x_reset_settings(struct nfc_device *pnd) { + int res = 0; // Reset the ending transmission bits register, it is unknown what the last tranmission used there CHIP_DATA (pnd)->ui8TxBits = 0; - if (!pn53x_write_register (pnd, PN53X_REG_CIU_BitFraming, SYMBOL_TX_LAST_BITS, 0x00)) { - return false; + if ((res = pn53x_write_register (pnd, PN53X_REG_CIU_BitFraming, SYMBOL_TX_LAST_BITS, 0x00)) < 0) { + return res; } - return true; + return NFC_SUCCESS; } -bool -pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t *pszRx, struct timeval *timeout) +int +pn53x_transceive (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRxLen, int timeout) { + int res = 0; if (CHIP_DATA (pnd)->wb_trigged) { - if (!pn53x_writeback_register (pnd)) { - return false; + if ((res = pn53x_writeback_register (pnd)) < 0) { + return res; } } PNCMD_TRACE (pbtTx[0]); - if (timeout) - log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Timeout values: %li s, %li us", timeout->tv_sec, timeout->tv_usec); + if (timeout > 0) { + log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Timeout values: %d", timeout); + } else if (timeout == 0) { + log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "No timeout"); + } else if (timeout == -1) { + timeout = CHIP_DATA (pnd)->timeout_command; + } else { + log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Invalid timeout value: %d", timeout); + } - byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szRx = sizeof(abtRx); // Check if receiving buffers are available, if not, replace them - if (!pszRx || !pbtRx) { + if (szRxLen == 0 || !pbtRx) { pbtRx = abtRx; - pszRx = &szRx; + } else { + szRx = szRxLen; } // Call the send/receice callback functions of the current driver - if (!CHIP_DATA (pnd)->io->send (pnd, pbtTx, szTx, timeout)) - return false; + if ((res = CHIP_DATA (pnd)->io->send (pnd, pbtTx, szTx, timeout)) < 0) { + return res; + } // Command is sent, we store the command - CHIP_DATA (pnd)->ui8LastCommand = pbtTx[0]; + CHIP_DATA (pnd)->last_command = pbtTx[0]; // Handle power mode for PN532 if ((CHIP_DATA (pnd)->type == PN532) && (TgInitAsTarget == pbtTx[0])) { // PN532 automatically goes into PowerDown mode when TgInitAsTarget command will be sent CHIP_DATA (pnd)->power_mode = POWERDOWN; } - int res = CHIP_DATA(pnd)->io->receive (pnd, pbtRx, *pszRx, timeout); - if (res < 0) { - return false; + if ((res = CHIP_DATA(pnd)->io->receive (pnd, pbtRx, szRx, timeout)) < 0) { + return res; } - if (pnd->iLastError) - return false; - if ((CHIP_DATA(pnd)->type == PN532) && (TgInitAsTarget == pbtTx[0])) { // PN532 automatically wakeup on external RF field CHIP_DATA(pnd)->power_mode = NORMAL; // When TgInitAsTarget reply that means an external RF have waken up the chip } - *pszRx = (size_t) res; + szRx = (size_t) res; switch (pbtTx[0]) { case PowerDown: case InDataExchange: @@ -161,81 +171,137 @@ pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, b case TgResponseToInitiator: case TgSetGeneralBytes: case TgSetMetaData: - pnd->iLastError = pbtRx[0] & 0x3f; + if (pbtRx[0] & 0x80) { abort(); } // NAD detected + if (pbtRx[0] & 0x40) { abort(); } // MI detected + CHIP_DATA(pnd)->last_status_byte = pbtRx[0] & 0x3f; break; case InDeselect: case InRelease: if (CHIP_DATA(pnd)->type == RCS360) { // Error code is in pbtRx[1] but we ignore error code anyway // because other PN53x chips always return 0 on those commands - pnd->iLastError = 0; + CHIP_DATA(pnd)->last_status_byte = 0; break; } - pnd->iLastError = pbtRx[0] & 0x3f; + CHIP_DATA(pnd)->last_status_byte = pbtRx[0] & 0x3f; break; case ReadRegister: case WriteRegister: if (CHIP_DATA(pnd)->type == PN533) { // PN533 prepends its answer by the status byte - pnd->iLastError = pbtRx[0] & 0x3f; + CHIP_DATA(pnd)->last_status_byte = pbtRx[0] & 0x3f; } else { - pnd->iLastError = 0; + CHIP_DATA(pnd)->last_status_byte = 0; } break; default: - pnd->iLastError = 0; + CHIP_DATA(pnd)->last_status_byte = 0; } - log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Last command status: %s", pn53x_strerror(pnd)); - return (0 == pnd->iLastError); + + switch (CHIP_DATA(pnd)->last_status_byte) { + case 0: + res = (int)szRx; + break; + case ETIMEOUT: + case ECRC: + case EPARITY: + case EBITCOUNT: + case EFRAMING: + case EBITCOLL: + case ERFPROTO: + case ERFTIMEOUT: + case EDEPUNKCMD: + case EDEPINVSTATE: + case ENAD: + case ENFCID3: + case EINVRXFRAM: + case EBCC: + case ECID: + res = NFC_ERFTRANS; + break; + case ESMALLBUF: + case EOVCURRENT: + case EBUFOVF: + case EOVHEAT: + case EINBUFOVF: + res = NFC_ECHIP; + break; + case EINVPARAM: + case EOPNOTALL: + case ECMD: + case ENSECNOTSUPP: + res = NFC_EINVARG; + break; + case ETGREL: + case ECDISCARDED: + res = NFC_ETGRELEASED; + break; + default: + res = NFC_ECHIP; + break; + }; +/* + { EMFAUTH, "Mifare Authentication Error" }, +*/ + + if (res < 0) { + pnd->last_error = res; + log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Chip error: \"%s\" (%02x), returned error: \"%s\" (%d))", pn53x_strerror (pnd), CHIP_DATA(pnd)->last_status_byte, nfc_strerror (pnd), res); + } else { + pnd->last_error = 0; + } + return res; } -bool -pn53x_set_parameters (nfc_device_t * pnd, const uint8_t ui8Parameter, const bool bEnable) +int +pn53x_set_parameters (struct nfc_device *pnd, const uint8_t ui8Parameter, const bool bEnable) { uint8_t ui8Value = (bEnable) ? (CHIP_DATA (pnd)->ui8Parameters | ui8Parameter) : (CHIP_DATA (pnd)->ui8Parameters & ~(ui8Parameter)); if (ui8Value != CHIP_DATA (pnd)->ui8Parameters) { return pn53x_SetParameters(pnd, ui8Value); } - return true; + return NFC_SUCCESS; } -bool -pn53x_set_tx_bits (nfc_device_t * pnd, const uint8_t ui8Bits) +int +pn53x_set_tx_bits (struct nfc_device *pnd, const uint8_t ui8Bits) { + int res = 0; // Test if we need to update the transmission bits register setting if (CHIP_DATA (pnd)->ui8TxBits != ui8Bits) { // Set the amount of transmission bits in the PN53X chip register - if (!pn53x_write_register (pnd, PN53X_REG_CIU_BitFraming, SYMBOL_TX_LAST_BITS, ui8Bits)) - return false; + if ((res = pn53x_write_register (pnd, PN53X_REG_CIU_BitFraming, SYMBOL_TX_LAST_BITS, ui8Bits)) < 0) + return res; // Store the new setting CHIP_DATA (pnd)->ui8TxBits = ui8Bits; } - return true; + return NFC_SUCCESS; } -bool -pn53x_wrap_frame (const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, - byte_t * pbtFrame, size_t * pszFrameBits) +int +pn53x_wrap_frame (const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, + uint8_t *pbtFrame) { - byte_t btFrame; - byte_t btData; + uint8_t btFrame; + uint8_t btData; uint32_t uiBitPos; uint32_t uiDataPos = 0; size_t szBitsLeft = szTxBits; + size_t szFrameBits = 0; // Make sure we should frame at least something if (szBitsLeft == 0) - return false; + return NFC_ECHIP; // Handle a short response (1byte) as a special case if (szBitsLeft < 9) { *pbtFrame = *pbtTx; - *pszFrameBits = szTxBits; - return true; + szFrameBits = szTxBits; + return szFrameBits; } // We start by calculating the frame length in bits - *pszFrameBits = szTxBits + (szTxBits / 8); + szFrameBits = szTxBits + (szTxBits / 8); // Parse the data bytes and add the parity bits // This is really a sensitive process, mirror the frame bytes and append parity bits @@ -262,7 +328,7 @@ pn53x_wrap_frame (const byte_t * pbtTx, const size_t szTxBits, const byte_t * pb uiDataPos++; // Test if we are done if (szBitsLeft < 9) - return true; + return szFrameBits; szBitsLeft -= 8; } // Every 8 data bytes we lose one frame byte to the parities @@ -270,29 +336,29 @@ pn53x_wrap_frame (const byte_t * pbtTx, const size_t szTxBits, const byte_t * pb } } -bool -pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t * pbtRx, size_t * pszRxBits, - byte_t * pbtRxPar) +int +pn53x_unwrap_frame (const uint8_t *pbtFrame, const size_t szFrameBits, uint8_t *pbtRx, uint8_t *pbtRxPar) { - byte_t btFrame; - byte_t btData; + uint8_t btFrame; + uint8_t btData; uint8_t uiBitPos; uint32_t uiDataPos = 0; - byte_t *pbtFramePos = (byte_t *) pbtFrame; + uint8_t *pbtFramePos = (uint8_t *) pbtFrame; size_t szBitsLeft = szFrameBits; + size_t szRxBits = 0; // Make sure we should frame at least something if (szBitsLeft == 0) - return false; + return NFC_ECHIP; // Handle a short response (1byte) as a special case if (szBitsLeft < 9) { *pbtRx = *pbtFrame; - *pszRxBits = szFrameBits; - return true; + szRxBits = szFrameBits; + return szRxBits; } // Calculate the data length in bits - *pszRxBits = szFrameBits - (szFrameBits / 9); + szRxBits = szFrameBits - (szFrameBits / 9); // Parse the frame bytes, remove the parity bits and store them in the parity array // This process is the reverse of WrapFrame(), look there for more info @@ -309,7 +375,7 @@ pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t * uiDataPos++; // Test if we are done if (szBitsLeft < 9) - return true; + return szRxBits; szBitsLeft -= 9; } // Every 8 data bytes we lose one frame byte to the parities @@ -317,9 +383,9 @@ pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t * } } -bool -pn53x_decode_target_data (const byte_t * pbtRawData, size_t szRawData, pn53x_type type, nfc_modulation_type_t nmt, - nfc_target_info_t * pnti) +int +pn53x_decode_target_data (const uint8_t *pbtRawData, size_t szRawData, pn53x_type type, nfc_modulation_type nmt, + nfc_target_info *pnti) { uint8_t szAttribRes; @@ -392,7 +458,7 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szRawData, pn53x_typ // Skip V & T Addresses pbtRawData++; if (*pbtRawData != 0x07) { // 0x07 = REPGEN - return false; + return NFC_ECHIP; } pbtRawData++; // Store the UID @@ -455,22 +521,23 @@ pn53x_decode_target_data (const byte_t * pbtRawData, size_t szRawData, pn53x_typ memcpy (pnti->nji.btId, pbtRawData, 4); break; default: - return false; + return NFC_ECHIP; break; } - return true; + return NFC_SUCCESS; } -bool -pn53x_ReadRegister (nfc_device_t * pnd, uint16_t ui16RegisterAddress, uint8_t * ui8Value) +int +pn53x_ReadRegister (struct nfc_device *pnd, uint16_t ui16RegisterAddress, uint8_t *ui8Value) { - byte_t abtCmd[] = { ReadRegister, ui16RegisterAddress >> 8, ui16RegisterAddress & 0xff }; - byte_t abtRegValue[2]; + uint8_t abtCmd[] = { ReadRegister, ui16RegisterAddress >> 8, ui16RegisterAddress & 0xff }; + uint8_t abtRegValue[2]; size_t szRegValue = sizeof (abtRegValue); + int res = 0; PNREG_TRACE (ui16RegisterAddress); - if (!pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), abtRegValue, &szRegValue, NULL)) { - return false; + if ((res = pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), abtRegValue, szRegValue, -1)) < 0) { + return res; } if (CHIP_DATA(pnd)->type == PN533) { // PN533 prepends its answer by a status byte @@ -478,31 +545,32 @@ pn53x_ReadRegister (nfc_device_t * pnd, uint16_t ui16RegisterAddress, uint8_t * } else { *ui8Value = abtRegValue[0]; } - return true; + return NFC_SUCCESS; } -bool pn53x_read_register (nfc_device_t * pnd, uint16_t ui16RegisterAddress, uint8_t * ui8Value) +int pn53x_read_register (struct nfc_device *pnd, uint16_t ui16RegisterAddress, uint8_t *ui8Value) { return pn53x_ReadRegister (pnd, ui16RegisterAddress, ui8Value); } -bool -pn53x_WriteRegister (nfc_device_t * pnd, const uint16_t ui16RegisterAddress, const uint8_t ui8Value) +int +pn53x_WriteRegister (struct nfc_device *pnd, const uint16_t ui16RegisterAddress, const uint8_t ui8Value) { - byte_t abtCmd[] = { WriteRegister, ui16RegisterAddress >> 8, ui16RegisterAddress & 0xff, ui8Value }; + uint8_t abtCmd[] = { WriteRegister, ui16RegisterAddress >> 8, ui16RegisterAddress & 0xff, ui8Value }; PNREG_TRACE (ui16RegisterAddress); - return pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL, NULL); + return pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, 0, -1); } -bool -pn53x_write_register (nfc_device_t * pnd, const uint16_t ui16RegisterAddress, const uint8_t ui8SymbolMask, const uint8_t ui8Value) +int +pn53x_write_register (struct nfc_device *pnd, const uint16_t ui16RegisterAddress, const uint8_t ui8SymbolMask, const uint8_t ui8Value) { + int res = 0; if ((ui16RegisterAddress < PN53X_CACHE_REGISTER_MIN_ADDRESS) || (ui16RegisterAddress > PN53X_CACHE_REGISTER_MAX_ADDRESS)) { // Direct write if (ui8SymbolMask != 0xff) { uint8_t ui8CurrentValue; - if (!pn53x_read_register (pnd, ui16RegisterAddress, &ui8CurrentValue)) - return false; + if ((res = pn53x_read_register (pnd, ui16RegisterAddress, &ui8CurrentValue)) < 0) + return res; uint8_t ui8NewValue = ((ui8Value & ui8SymbolMask) | (ui8CurrentValue & (~ui8SymbolMask))); if (ui8NewValue != ui8CurrentValue) { return pn53x_WriteRegister (pnd, ui16RegisterAddress, ui8NewValue); @@ -517,12 +585,13 @@ pn53x_write_register (nfc_device_t * pnd, const uint16_t ui16RegisterAddress, co CHIP_DATA (pnd)->wb_mask[internal_address] = CHIP_DATA (pnd)->wb_mask[internal_address] | ui8SymbolMask; CHIP_DATA (pnd)->wb_trigged = true; } - return true; + return NFC_SUCCESS; } -bool -pn53x_writeback_register (nfc_device_t * pnd) +int +pn53x_writeback_register (struct nfc_device *pnd) { + int res = 0; // TODO Check at each step (ReadRegister, WriteRegister) if we didn't exceed max supported frame length BUFFER_INIT (abtReadRegisterCmd, PN53x_EXTENDED_FRAME__DATA_MAX_LEN); BUFFER_APPEND (abtReadRegisterCmd, ReadRegister); @@ -543,8 +612,8 @@ pn53x_writeback_register (nfc_device_t * pnd) uint8_t abtRes[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szRes = sizeof(abtRes); // It transceives the previously constructed ReadRegister command - if (!pn53x_transceive (pnd, abtReadRegisterCmd, BUFFER_SIZE (abtReadRegisterCmd), abtRes, &szRes, NULL)) { - return false; + if ((res = pn53x_transceive (pnd, abtReadRegisterCmd, BUFFER_SIZE (abtReadRegisterCmd), abtRes, szRes, -1)) < 0) { + return res; } size_t i = 0; if (CHIP_DATA(pnd)->type == PN533) { @@ -581,22 +650,24 @@ pn53x_writeback_register (nfc_device_t * pnd) if (BUFFER_SIZE (abtWriteRegisterCmd) > 1) { // We need to write some registers - if (!pn53x_transceive (pnd, abtWriteRegisterCmd, BUFFER_SIZE (abtWriteRegisterCmd), NULL, NULL, NULL)) { - return false; + if ((res = pn53x_transceive (pnd, abtWriteRegisterCmd, BUFFER_SIZE (abtWriteRegisterCmd), NULL, 0, -1)) < 0) { + return res; } } - return true; + return NFC_SUCCESS; } -bool -pn53x_get_firmware_version (nfc_device_t * pnd, char abtFirmwareText[22]) +int +pn53x_get_firmware_version (struct nfc_device *pnd, char abtFirmwareText[22]) { - const byte_t abtCmd[] = { GetFirmwareVersion }; - byte_t abtFw[4]; + const uint8_t abtCmd[] = { GetFirmwareVersion }; + uint8_t abtFw[4]; size_t szFwLen = sizeof (abtFw); - if (!pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), abtFw, &szFwLen, NULL)) { - return false; + int res = 0; + if ((res = pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), abtFw, szFwLen, -1)) < 0) { + return res; } + szFwLen = (size_t) res; // Determine which version of chip it is: PN531 will return only 2 bytes, while others return 4 bytes and have the first to tell the version IC if (szFwLen == 2) { CHIP_DATA(pnd)->type = PN531; @@ -611,11 +682,11 @@ pn53x_get_firmware_version (nfc_device_t * pnd, char abtFirmwareText[22]) } } else { // Unknown version IC - return false; + return NFC_ENOTIMPL; } } else { // Unknown chip - return false; + return NFC_ENOTIMPL; } // Convert firmware info in text, PN531 gives 2 bytes info, but PN532 and PN533 gives 4 switch (CHIP_DATA(pnd)->type) { @@ -636,183 +707,217 @@ pn53x_get_firmware_version (nfc_device_t * pnd, char abtFirmwareText[22]) // Could not happend break; } - return true; + return NFC_SUCCESS; } -bool -pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable) +uint8_t +pn53x_int_to_timeout (const int ms) { - byte_t btValue; - switch (ndo) { - case NDO_HANDLE_CRC: + uint8_t res = 0; + if (ms) { + res = 0x10; + for (int i=3280; i>1; i/=2) { + if (ms > i) + break; + res--; + } + } + return res; +} + +int +pn53x_set_property_int (struct nfc_device *pnd, const nfc_property property, const int value) +{ + switch (property) { + case NP_TIMEOUT_COMMAND: + CHIP_DATA (pnd)->timeout_command = value; + break; + case NP_TIMEOUT_ATR: + CHIP_DATA (pnd)->timeout_atr = value; + return pn53x_RFConfiguration__Various_timings (pnd, pn53x_int_to_timeout(CHIP_DATA (pnd)->timeout_atr), pn53x_int_to_timeout(CHIP_DATA (pnd)->timeout_communication)); + break; + case NP_TIMEOUT_COM: + CHIP_DATA (pnd)->timeout_communication = value; + return pn53x_RFConfiguration__Various_timings (pnd, pn53x_int_to_timeout(CHIP_DATA (pnd)->timeout_atr), pn53x_int_to_timeout(CHIP_DATA (pnd)->timeout_communication)); + break; + default: + return NFC_EINVARG; + } + return NFC_SUCCESS; +} + +int +pn53x_set_property_bool (struct nfc_device *pnd, const nfc_property property, const bool bEnable) +{ + uint8_t btValue; + int res = 0; + switch (property) { + case NP_HANDLE_CRC: // Enable or disable automatic receiving/sending of CRC bytes if (bEnable == pnd->bCrc) { // Nothing to do - return true; + return NFC_SUCCESS; } // TX and RX are both represented by the symbol 0x80 btValue = (bEnable) ? 0x80 : 0x00; - if (!pn53x_write_register (pnd, PN53X_REG_CIU_TxMode, SYMBOL_TX_CRC_ENABLE, btValue)) - return false; - if (!pn53x_write_register (pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_CRC_ENABLE, btValue)) - return false; + if ((res = pn53x_write_register (pnd, PN53X_REG_CIU_TxMode, SYMBOL_TX_CRC_ENABLE, btValue)) < 0) + return res; + if ((res = pn53x_write_register (pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_CRC_ENABLE, btValue)) < 0) + return res; pnd->bCrc = bEnable; + return NFC_SUCCESS; break; - case NDO_HANDLE_PARITY: + case NP_HANDLE_PARITY: // Handle parity bit by PN53X chip or parse it as data bit if (bEnable == pnd->bPar) // Nothing to do - return true; + return NFC_SUCCESS; btValue = (bEnable) ? 0x00 : SYMBOL_PARITY_DISABLE; - if (!pn53x_write_register (pnd, PN53X_REG_CIU_ManualRCV, SYMBOL_PARITY_DISABLE, btValue)) - return false; + if ((res = pn53x_write_register (pnd, PN53X_REG_CIU_ManualRCV, SYMBOL_PARITY_DISABLE, btValue)) < 0) + return res; pnd->bPar = bEnable; + return NFC_SUCCESS; break; - case NDO_EASY_FRAMING: + case NP_EASY_FRAMING: pnd->bEasyFraming = bEnable; + return NFC_SUCCESS; break; - case NDO_ACTIVATE_FIELD: + case NP_ACTIVATE_FIELD: { - return pn53x_RFConfiguration__RF_field (pnd, bEnable); + if (pn53x_RFConfiguration__RF_field (pnd, bEnable) == 0) + return NFC_SUCCESS; } break; - case NDO_ACTIVATE_CRYPTO1: + case NP_ACTIVATE_CRYPTO1: btValue = (bEnable) ? SYMBOL_MF_CRYPTO1_ON : 0x00; - if (!pn53x_write_register (pnd, PN53X_REG_CIU_Status2, SYMBOL_MF_CRYPTO1_ON, btValue)) - return false; + return pn53x_write_register (pnd, PN53X_REG_CIU_Status2, SYMBOL_MF_CRYPTO1_ON, btValue); break; - case NDO_INFINITE_SELECT: + case NP_INFINITE_SELECT: { // TODO Made some research around this point: // timings could be tweak better than this, and maybe we can tweak timings // to "gain" a sort-of hardware polling (ie. like PN532 does) - return pn53x_RFConfiguration__MaxRetries (pnd, + if (pn53x_RFConfiguration__MaxRetries (pnd, (bEnable) ? 0xff : 0x00, // MxRtyATR, default: active = 0xff, passive = 0x02 - (bEnable) ? 0xff : 0x00, // MxRtyPSL, default: 0x01 + (bEnable) ? 0xff : 0x01, // MxRtyPSL, default: 0x01 (bEnable) ? 0xff : 0x02 // MxRtyPassiveActivation, default: 0xff (0x00 leads to problems with PN531) - ); + ) == 0) + return NFC_SUCCESS; } break; - case NDO_ACCEPT_INVALID_FRAMES: + case NP_ACCEPT_INVALID_FRAMES: btValue = (bEnable) ? SYMBOL_RX_NO_ERROR : 0x00; - if (!pn53x_write_register (pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_NO_ERROR, btValue)) - return false; + return pn53x_write_register (pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_NO_ERROR, btValue); break; - case NDO_ACCEPT_MULTIPLE_FRAMES: + case NP_ACCEPT_MULTIPLE_FRAMES: btValue = (bEnable) ? SYMBOL_RX_MULTIPLE : 0x00; - if (!pn53x_write_register (pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_MULTIPLE, btValue)) - return false; - return true; + return pn53x_write_register (pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_MULTIPLE, btValue); break; - case NDO_AUTO_ISO14443_4: + case NP_AUTO_ISO14443_4: if (bEnable == pnd->bAutoIso14443_4) // Nothing to do - return true; + return NFC_SUCCESS; pnd->bAutoIso14443_4 = bEnable; - return pn53x_set_parameters (pnd, PARAM_AUTO_RATS, bEnable); + if (pn53x_set_parameters (pnd, PARAM_AUTO_RATS, bEnable) == 0) + return NFC_SUCCESS; break; - case NDO_FORCE_ISO14443_A: + case NP_FORCE_ISO14443_A: if(!bEnable) { // Nothing to do - return true; + return NFC_SUCCESS; } // Force pn53x to be in ISO14443-A mode - if (!pn53x_write_register (pnd, PN53X_REG_CIU_TxMode, SYMBOL_TX_FRAMING, 0x00)) { - return false; + if ((res = pn53x_write_register (pnd, PN53X_REG_CIU_TxMode, SYMBOL_TX_FRAMING, 0x00)) < 0) { + return res; } - if (!pn53x_write_register (pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_FRAMING, 0x00)) { - return false; + if ((res = pn53x_write_register (pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_FRAMING, 0x00)) < 0) { + return res; } // Set the PN53X to force 100% ASK Modified miller decoding (default for 14443A cards) - if (!pn53x_write_register (pnd, PN53X_REG_CIU_TxAuto, SYMBOL_FORCE_100_ASK, 0x40)) - return false; - - return true; + return pn53x_write_register (pnd, PN53X_REG_CIU_TxAuto, SYMBOL_FORCE_100_ASK, 0x40); break; - case NDO_FORCE_ISO14443_B: + case NP_FORCE_ISO14443_B: if(!bEnable) { // Nothing to do - return true; + return NFC_SUCCESS; } // Force pn53x to be in ISO14443-B mode - if (!pn53x_write_register (pnd, PN53X_REG_CIU_TxMode, SYMBOL_TX_FRAMING, 0x03)) { - return false; + if ((res = pn53x_write_register (pnd, PN53X_REG_CIU_TxMode, SYMBOL_TX_FRAMING, 0x03)) < 0) { + return res; } - if (!pn53x_write_register (pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_FRAMING, 0x03)) { - return false; - } - - return true; + return pn53x_write_register (pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_FRAMING, 0x03); break; - case NDO_FORCE_SPEED_106: + case NP_FORCE_SPEED_106: if(!bEnable) { // Nothing to do - return true; + return NFC_SUCCESS; } // Force pn53x to be at 106 kbps - if (!pn53x_write_register (pnd, PN53X_REG_CIU_TxMode, SYMBOL_TX_SPEED, 0x00)) { - return false; + if ((res = pn53x_write_register (pnd, PN53X_REG_CIU_TxMode, SYMBOL_TX_SPEED, 0x00)) < 0) { + return res; } - if (!pn53x_write_register (pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_SPEED, 0x00)) { - return false; - } - - return true; + return pn53x_write_register (pnd, PN53X_REG_CIU_RxMode, SYMBOL_RX_SPEED, 0x00); + break; + // Not boolean property + case NP_TIMEOUT_COMMAND: + case NP_TIMEOUT_ATR: + case NP_TIMEOUT_COM: + return NFC_EINVARG; break; } - // When we reach this, the configuration is completed and successful - return true; + return NFC_EINVARG; } -bool -pn53x_idle (nfc_device_t *pnd) +int +pn53x_idle (struct nfc_device *pnd) { + int res = 0; switch (CHIP_DATA (pnd)->operating_mode) { case TARGET: // InRelease used in target mode stops the target emulation and no more // tag are seen from external initiator - if (!pn53x_InRelease (pnd, 0)) { - return false; + if ((res = pn53x_InRelease (pnd, 0)) < 0) { + return res; } if (CHIP_DATA (pnd)->type == PN532) { // Use PowerDown to go in "Low VBat" power mode - if (!pn53x_PowerDown (pnd)) { - return false; + if ((res = pn53x_PowerDown (pnd)) < 0) { + return res; } CHIP_DATA (pnd)->power_mode = LOWVBAT; } break; case INITIATOR: // Deselect all active communications - if (!pn53x_InDeselect (pnd, 0)) { - return false; + if ((res = pn53x_InDeselect (pnd, 0)) < 0) { + return res; } // Disable RF field to avoid heating - if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) { - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_ACTIVATE_FIELD, false)) < 0) { + return res; } if (CHIP_DATA (pnd)->type == PN532) { // Use PowerDown to go in "Low VBat" power mode - if (!pn53x_PowerDown (pnd)) { - return false; + if ((res = pn53x_PowerDown (pnd)) < 0) { + return res; } CHIP_DATA (pnd)->power_mode = LOWVBAT; } else { // Use InRelease to go in "Standby mode" - if (!pn53x_InRelease (pnd, 0)) { - return false; + if ((res = pn53x_InRelease (pnd, 0)) < 0) { + return res; } } break; @@ -821,173 +926,173 @@ pn53x_idle (nfc_device_t *pnd) break; }; CHIP_DATA (pnd)->operating_mode = IDLE; - return true; + return NFC_SUCCESS; } -bool -pn53x_check_communication (nfc_device_t *pnd) +int +pn53x_check_communication (struct nfc_device *pnd) { - const byte_t abtCmd[] = { Diagnose, 0x00, 'l', 'i', 'b', 'n', 'f', 'c' }; - const byte_t abtExpectedRx[] = { 0x00, 'l', 'i', 'b', 'n', 'f', 'c' }; - byte_t abtRx[sizeof(abtExpectedRx)]; + const uint8_t abtCmd[] = { Diagnose, 0x00, 'l', 'i', 'b', 'n', 'f', 'c' }; + const uint8_t abtExpectedRx[] = { 0x00, 'l', 'i', 'b', 'n', 'f', 'c' }; + uint8_t abtRx[sizeof(abtExpectedRx)]; size_t szRx = sizeof (abtRx); + int res = 0; - struct timeval timeout; - timeout.tv_sec = 1; - timeout.tv_usec = 0; - - if (!pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), abtRx, &szRx, &timeout)) - return false; - - return ((sizeof(abtExpectedRx) == szRx) && (0 == memcmp (abtRx, abtExpectedRx, sizeof(abtExpectedRx)))); + if ((res = pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), abtRx, szRx, 500)) < 0) + return res; + szRx = (size_t) res; + if ((sizeof(abtExpectedRx) == szRx) && (0 == memcmp (abtRx, abtExpectedRx, sizeof(abtExpectedRx)))) + return NFC_SUCCESS; + + return NFC_EIO; } -bool -pn53x_initiator_init (nfc_device_t * pnd) +int +pn53x_initiator_init (struct nfc_device *pnd) { pn53x_reset_settings(pnd); + int res = 0; // Configure the PN53X to be an Initiator or Reader/Writer - if (!pn53x_write_register (pnd, PN53X_REG_CIU_Control, SYMBOL_INITIATOR, 0x10)) - return false; + if ((res = pn53x_write_register (pnd, PN53X_REG_CIU_Control, SYMBOL_INITIATOR, 0x10)) < 0) + return res; CHIP_DATA (pnd)->operating_mode = INITIATOR; - return true; + return NFC_SUCCESS; } -bool -pn53x_initiator_select_passive_target_ext (nfc_device_t * pnd, - const nfc_modulation_t nm, - const byte_t * pbtInitData, const size_t szInitData, - nfc_target_t * pnt, - struct timeval* timeout) +int +pn53x_initiator_select_passive_target_ext (struct nfc_device *pnd, + const nfc_modulation nm, + const uint8_t *pbtInitData, const size_t szInitData, + nfc_target *pnt, + int timeout) { - byte_t abtTargetsData[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + uint8_t abtTargetsData[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szTargetsData = sizeof(abtTargetsData); + int res = 0; if (nm.nmt == NMT_ISO14443BI || nm.nmt == NMT_ISO14443B2SR || nm.nmt == NMT_ISO14443B2CT) { if (CHIP_DATA(pnd)->type == RCS360) { // TODO add support for RC-S360, at the moment it refuses to send raw frames without a first select - pnd->iLastError = ENOTIMPL; - return false; + pnd->last_error = NFC_ENOTIMPL; + return pnd->last_error; } // No native support in InListPassiveTarget so we do discovery by hand - if (!nfc_configure (pnd, NDO_FORCE_ISO14443_B, true)) { - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_FORCE_ISO14443_B, true)) < 0) { + return res; } - if (!nfc_configure (pnd, NDO_FORCE_SPEED_106, true)) { - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_FORCE_SPEED_106, true)) < 0) { + return res; } - if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) { - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_HANDLE_CRC, true)) < 0) { + return res; } pnd->bEasyFraming = false; if (nm.nmt == NMT_ISO14443B2SR) { // Some work to do before getting the UID... - byte_t abtInitiate[]="\x06\x00"; + uint8_t abtInitiate[]="\x06\x00"; size_t szInitiateLen = 2; - byte_t abtSelect[]="\x0e\x00"; + uint8_t abtSelect[]="\x0e\x00"; size_t szSelectLen = 2; - byte_t abtRx[1]; + uint8_t abtRx[1]; size_t szRxLen = 1; // Getting random Chip_ID - if (!pn53x_initiator_transceive_bytes (pnd, abtInitiate, szInitiateLen, abtRx, &szRxLen, timeout)) { - return false; + if ((res = pn53x_initiator_transceive_bytes (pnd, abtInitiate, szInitiateLen, abtRx, &szRxLen, timeout)) < 0) { + return res; } abtSelect[1] = abtRx[0]; - if (!pn53x_initiator_transceive_bytes (pnd, abtSelect, szSelectLen, abtRx, &szRxLen, timeout)) { - return false; + if ((res = pn53x_initiator_transceive_bytes (pnd, abtSelect, szSelectLen, abtRx, &szRxLen, timeout)) < 0) { + return res; } } else if (nm.nmt == NMT_ISO14443B2CT) { // Some work to do before getting the UID... - byte_t abtReqt[]="\x10"; + uint8_t abtReqt[]="\x10"; size_t szReqtLen = 1; // Getting product code / fab code & store it in output buffer after the serial nr we'll obtain later - if (!pn53x_initiator_transceive_bytes (pnd, abtReqt, szReqtLen, abtTargetsData+2, &szTargetsData, timeout) || szTargetsData != 2) { - return false; + if ((res = pn53x_initiator_transceive_bytes (pnd, abtReqt, szReqtLen, abtTargetsData+2, &szTargetsData, timeout)) < 0) { + return res; } } - if (!pn53x_initiator_transceive_bytes (pnd, pbtInitData, szInitData, abtTargetsData, &szTargetsData, timeout)) { - return false; + if ((res = pn53x_initiator_transceive_bytes (pnd, pbtInitData, szInitData, abtTargetsData, &szTargetsData, timeout)) < 0) { + return res; } if (nm.nmt == NMT_ISO14443B2CT) { if (szTargetsData != 2) - return false; - byte_t abtRead[]="\xC4"; // Reading UID_MSB (Read address 4) + return NFC_ECHIP; + uint8_t abtRead[]="\xC4"; // Reading UID_MSB (Read address 4) size_t szReadLen = 1; - if (!pn53x_initiator_transceive_bytes (pnd, abtRead, szReadLen, abtTargetsData+4, &szTargetsData, timeout) || szTargetsData != 2) { - return false; + if ((res = pn53x_initiator_transceive_bytes (pnd, abtRead, szReadLen, abtTargetsData+4, &szTargetsData, timeout) < 0)) { + return res; } szTargetsData = 6; // u16 UID_LSB, u8 prod code, u8 fab code, u16 UID_MSB } if (pnt) { pnt->nm = nm; // Fill the tag info struct with the values corresponding to this init modulation - if (!pn53x_decode_target_data (abtTargetsData, szTargetsData, CHIP_DATA(pnd)->type, nm.nmt, &(pnt->nti))) { - return false; + if ((res = pn53x_decode_target_data (abtTargetsData, szTargetsData, CHIP_DATA(pnd)->type, nm.nmt, &(pnt->nti))) < 0 ) { + return res; } } if (nm.nmt == NMT_ISO14443BI) { // Select tag - byte_t abtAttrib[6]; + uint8_t abtAttrib[6]; size_t szAttribLen = sizeof(abtAttrib); memcpy(abtAttrib, abtTargetsData, szAttribLen); abtAttrib[1] = 0x0f; // ATTRIB - if (!pn53x_initiator_transceive_bytes (pnd, abtAttrib, szAttribLen, NULL, NULL, timeout)) { - return false; + if ((res = pn53x_initiator_transceive_bytes (pnd, abtAttrib, szAttribLen, NULL, NULL, timeout)) < 0) { + return res; } } - return true; + return abtTargetsData[0]; } // else: - const pn53x_modulation_t pm = pn53x_nm_to_pm(nm); + const pn53x_modulation pm = pn53x_nm_to_pm(nm); if (PM_UNDEFINED == pm) { - pnd->iLastError = EINVALARG; - return false; + pnd->last_error = NFC_EINVARG; + return pnd->last_error; } - if (!pn53x_InListPassiveTarget (pnd, pm, 1, pbtInitData, szInitData, abtTargetsData, &szTargetsData, timeout)) - return false; - - // Make sure one tag has been found, the PN53X returns 0x00 if none was available - if (abtTargetsData[0] == 0) - return false; + if ((res = pn53x_InListPassiveTarget (pnd, pm, 1, pbtInitData, szInitData, abtTargetsData, &szTargetsData, timeout)) <= 0) + return res; // Is a tag info struct available if (pnt) { pnt->nm = nm; // Fill the tag info struct with the values corresponding to this init modulation - if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, CHIP_DATA(pnd)->type, nm.nmt, &(pnt->nti))) { - return false; + if ((res = pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, CHIP_DATA(pnd)->type, nm.nmt, &(pnt->nti)) < 0)) { + return res; } } - return true; + return abtTargetsData[0]; } -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) +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) { - return pn53x_initiator_select_passive_target_ext (pnd, nm, pbtInitData, szInitData, pnt, NULL); + return pn53x_initiator_select_passive_target_ext (pnd, nm, pbtInitData, szInitData, pnt, 0); } -bool -pn53x_initiator_poll_target (nfc_device_t * pnd, - const nfc_modulation_t * pnmModulations, const size_t szModulations, +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) + nfc_target *pnt) { + int res = 0; + if (CHIP_DATA(pnd)->type == PN532) { size_t szTargetTypes = 0; - pn53x_target_type_t apttTargetTypes[32]; - for (size_t n=0; niLastError = EINVALARG; - return false; + pnd->last_error = NFC_EINVARG; + return pnd->last_error; } apttTargetTypes[szTargetTypes] = ptt; if ((pnd->bAutoIso14443_4) && (ptt == PTT_MIFARE)) { // Hack to have ATS @@ -997,58 +1102,58 @@ pn53x_initiator_poll_target (nfc_device_t * pnd, } szTargetTypes++; } - size_t szTargetFound = 0; - nfc_target_t ntTargets[2]; - if (!pn53x_InAutoPoll (pnd, apttTargetTypes, szTargetTypes, uiPollNr, uiPeriod, ntTargets, &szTargetFound)) - return false; - switch (szTargetFound) { + nfc_target ntTargets[2]; + if ((res = pn53x_InAutoPoll (pnd, apttTargetTypes, szTargetTypes, uiPollNr, uiPeriod, ntTargets, 0)) < 0) + return res; + switch (res) { case 1: *pnt = ntTargets[0]; - return true; + return res; break; case 2: *pnt = ntTargets[1]; // We keep the selected one - return true; + return res; break; default: - return false; + return NFC_ECHIP; break; } } else { - pn53x_configure (pnd, NDO_INFINITE_SELECT, true); + pn53x_set_property_bool (pnd, NP_INFINITE_SELECT, true); // FIXME It does not support DEP targets do { - for (size_t p=0; piLastError != ECOMTIMEOUT) - return false; + if ((res = pn53x_initiator_select_passive_target_ext (pnd, pnmModulations[n], pbtInitiatorData, szInitiatorData, pnt, timeout_ms)) < 0) { + if (pnd->last_error != NFC_ETIMEOUT) { + return pnd->last_error; + } } else { - return true; + return res; } } } } while (uiPollNr==0xff); // uiPollNr==0xff means infinite polling + // We reach this point when each listing give no result, we simply have to return 0 + return 0; } - return false; + return NFC_ECHIP; } -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) +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) { - const byte_t abtPassiveInitiatorData[] = { 0x00, 0xff, 0xff, 0x00, 0x00 }; // Only for 212/424 kpbs: First 4 bytes shall be set like this according to NFCIP-1, last byte is TSN (Time Slot Number) - const byte_t * pbtPassiveInitiatorData = NULL; + const uint8_t abtPassiveInitiatorData[] = { 0x00, 0xff, 0xff, 0x00, 0x0f }; // Only for 212/424 kpbs: First 4 bytes shall be set like this according to NFCIP-1, last byte is TSN (Time Slot Number) + const uint8_t * pbtPassiveInitiatorData = NULL; switch (nbr) { case NBR_212: @@ -1063,26 +1168,30 @@ pn53x_initiator_select_dep_target(nfc_device_t * pnd, } if (pndiInitiator) { - return pn53x_InJumpForDEP (pnd, ndm, nbr, pbtPassiveInitiatorData, pndiInitiator->abtNFCID3, pndiInitiator->abtGB, pndiInitiator->szGB, pnt); + return pn53x_InJumpForDEP (pnd, ndm, nbr, pbtPassiveInitiatorData, pndiInitiator->abtNFCID3, pndiInitiator->abtGB, pndiInitiator->szGB, pnt, timeout); } else { - return pn53x_InJumpForDEP (pnd, ndm, nbr, pbtPassiveInitiatorData, NULL, NULL, 0, pnt); + return pn53x_InJumpForDEP (pnd, ndm, nbr, pbtPassiveInitiatorData, NULL, NULL, 0, pnt, timeout); } } -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) +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 res = 0; size_t szFrameBits = 0; size_t szFrameBytes = 0; + size_t szRxBits = 0; uint8_t ui8rcc; uint8_t ui8Bits = 0; - byte_t abtCmd[PN53x_EXTENDED_FRAME__DATA_MAX_LEN] = { InCommunicateThru }; + uint8_t abtCmd[PN53x_EXTENDED_FRAME__DATA_MAX_LEN] = { InCommunicateThru }; // Check if we should prepare the parity bits ourself if (!pnd->bPar) { // Convert data with parity to a frame - pn53x_wrap_frame (pbtTx, szTxBits, pbtTxPar, abtCmd + 1, &szFrameBits); + if ((res = pn53x_wrap_frame (pbtTx, szTxBits, pbtTxPar, abtCmd + 1)) < 0) + return res; + szFrameBits = res; } else { szFrameBits = szTxBits; } @@ -1098,19 +1207,19 @@ pn53x_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const memcpy (abtCmd + 1, pbtTx, szFrameBytes); // Set the amount of transmission bits in the PN53X chip register - if (!pn53x_set_tx_bits (pnd, ui8Bits)) - return false; + if ((res = pn53x_set_tx_bits (pnd, ui8Bits)) < 0) + return res; // Send the frame to the PN53X chip and get the answer // We have to give the amount of bytes + (the command byte 0x42) - byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szRx = sizeof(abtRx); - if (!pn53x_transceive (pnd, abtCmd, szFrameBytes + 1, abtRx, &szRx, NULL)) - return false; - + if ((res = pn53x_transceive (pnd, abtCmd, szFrameBytes + 1, abtRx, szRx, -1)) < 0) + return res; + szRx = (size_t) res; // Get the last bit-count that is stored in the received byte - if (!pn53x_read_register (pnd, PN53X_REG_CIU_Control, &ui8rcc)) - return false; + if ((res = pn53x_read_register (pnd, PN53X_REG_CIU_Control, &ui8rcc)) < 0) + return res; ui8Bits = ui8rcc & SYMBOL_RX_LAST_BITS; // Recover the real frame length in bits @@ -1121,29 +1230,32 @@ pn53x_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const // Check if we should recover the parity bits ourself if (!pnd->bPar) { // Unwrap the response frame - pn53x_unwrap_frame (abtRx + 1, szFrameBits, pbtRx, pszRxBits, pbtRxPar); + if ((res = pn53x_unwrap_frame (abtRx + 1, szFrameBits, pbtRx, pbtRxPar)) < 0) + return res; + szRxBits = res; } else { // Save the received bits - *pszRxBits = szFrameBits; + szRxBits = szFrameBits; // Copy the received bytes memcpy (pbtRx, abtRx + 1, szRx - 1); } } // Everything went successful - return true; + return szRxBits; } -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) +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) { size_t szExtraTxLen; - byte_t abtCmd[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + uint8_t abtCmd[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + int res = 0; // We can not just send bytes without parity if while the PN53X expects we handled them if (!pnd->bPar) { - pnd->iLastError = EINVALARG; - return false; + pnd->last_error = NFC_EINVARG; + return pnd->last_error; } // Copy the data into the command frame @@ -1159,16 +1271,21 @@ pn53x_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, cons } // To transfer command frames bytes we can not have any leading bits, reset this to zero - if (!pn53x_set_tx_bits (pnd, 0)) - return false; + if ((res = pn53x_set_tx_bits (pnd, 0)) < 0) { + pnd->last_error = res; + return pnd->last_error; + } // Send the frame to the PN53X chip and get the answer // We have to give the amount of bytes + (the two command bytes 0xD4, 0x42) - byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szRx = sizeof(abtRx); - if (!pn53x_transceive (pnd, abtCmd, szTx + szExtraTxLen, abtRx, &szRx, timeout)) - return false; + if ((res = pn53x_transceive (pnd, abtCmd, szTx + szExtraTxLen, abtRx, szRx, timeout)) < 0) { + pnd->last_error = res; + return pnd->last_error; + } + szRx = (size_t) res; if (pbtRx != NULL) { // Save the received byte count *pszRx = szRx - 1; @@ -1176,11 +1293,11 @@ pn53x_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, cons // Copy the received bytes memcpy (pbtRx, abtRx + 1, *pszRx); } - // Everything went successful - return true; + // Everything went successful, we return received bytes count + return *pszRx; } -void __pn53x_init_timer(nfc_device_t * pnd, const uint32_t max_cycles) +void __pn53x_init_timer(struct nfc_device *pnd, const uint32_t max_cycles) { // The prescaler will dictate what will be the precision and // the largest delay to measure before saturation. Some examples: @@ -1201,7 +1318,7 @@ void __pn53x_init_timer(nfc_device_t * pnd, const uint32_t max_cycles) pn53x_write_register (pnd, PN53X_REG_CIU_TReloadVal_lo, 0xFF, reloadval & 0xFF); } -uint32_t __pn53x_get_timer(nfc_device_t * pnd, const uint8_t last_cmd_byte) +uint32_t __pn53x_get_timer(struct nfc_device *pnd, const uint8_t last_cmd_byte) { uint8_t parity; uint8_t counter_hi, counter_lo; @@ -1222,7 +1339,7 @@ uint32_t __pn53x_get_timer(nfc_device_t * pnd, const uint8_t last_cmd_byte) uint8_t abtRes[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szRes = sizeof(abtRes); // Let's send the previously constructed ReadRegister command - if (!pn53x_transceive (pnd, abtReadRegisterCmd, BUFFER_SIZE (abtReadRegisterCmd), abtRes, &szRes, NULL)) { + if (pn53x_transceive (pnd, abtReadRegisterCmd, BUFFER_SIZE (abtReadRegisterCmd), abtRes, szRes, -1) < 0) { return false; } counter_hi = abtRes[off]; @@ -1261,30 +1378,32 @@ uint32_t __pn53x_get_timer(nfc_device_t * pnd, const uint8_t last_cmd_byte) return u32cycles; } -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) +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) { // TODO Do something with these bytes... (void) pbtTxPar; (void) pbtRxPar; uint16_t i; uint8_t sz; + int res = 0; + size_t szRxBits = 0; // Sorry, no arbitrary parity bits support for now if (!pnd->bPar) { - pnd->iLastError = ENOTIMPL; - return false; + pnd->last_error = NFC_ENOTIMPL; + return pnd->last_error; } // Sorry, no easy framing support if (pnd->bEasyFraming) { - pnd->iLastError = ENOTIMPL; - return false; + pnd->last_error = NFC_ENOTIMPL; + return pnd->last_error; } // TODO CRC support but it probably doesn't make sense for (szTxBits % 8 != 0) ... if (pnd->bCrc) { - pnd->iLastError = ENOTIMPL; - return false; + pnd->last_error = NFC_ENOTIMPL; + return pnd->last_error; } __pn53x_init_timer(pnd, *cycles); @@ -1302,7 +1421,7 @@ pn53x_initiator_transceive_bits_timed (nfc_device_t * pnd, const byte_t * pbtTx, BUFFER_APPEND (abtWriteRegisterCmd, PN53X_REG_CIU_FIFOLevel >> 8); BUFFER_APPEND (abtWriteRegisterCmd, PN53X_REG_CIU_FIFOLevel & 0xff); BUFFER_APPEND (abtWriteRegisterCmd, SYMBOL_FLUSH_BUFFER); - for (i=0; i< ((szTxBits / 8) + 1); i++) { + for (i = 0; i < ((szTxBits / 8) + 1); i++) { BUFFER_APPEND (abtWriteRegisterCmd, PN53X_REG_CIU_FIFOData >> 8); BUFFER_APPEND (abtWriteRegisterCmd, PN53X_REG_CIU_FIFOData & 0xff); BUFFER_APPEND (abtWriteRegisterCmd, pbtTx[i]); @@ -1312,17 +1431,16 @@ pn53x_initiator_transceive_bits_timed (nfc_device_t * pnd, const byte_t * pbtTx, BUFFER_APPEND (abtWriteRegisterCmd, PN53X_REG_CIU_BitFraming & 0xff); BUFFER_APPEND (abtWriteRegisterCmd, SYMBOL_START_SEND | ((szTxBits % 8) & SYMBOL_TX_LAST_BITS)); // Let's send the previously constructed WriteRegister command - if (!pn53x_transceive (pnd, abtWriteRegisterCmd, BUFFER_SIZE (abtWriteRegisterCmd), NULL, NULL, NULL)) { - return false; + if ((res = pn53x_transceive (pnd, abtWriteRegisterCmd, BUFFER_SIZE (abtWriteRegisterCmd), NULL, 0, -1)) < 0) { + return res; } // Recv data - *pszRxBits = 0; // we've to watch for coming data until we decide to timeout. // our PN53x timer saturates after 4.8ms so this function shouldn't be used for // responses coming very late anyway. // Ideally we should implement a real timer here too but looping a few times is good enough. - for (i=0; i<(3 *(CHIP_DATA (pnd)->timer_prescaler * 2 + 1)); i++) { + for (i = 0; i < (3 *(CHIP_DATA (pnd)->timer_prescaler * 2 + 1)); i++) { pn53x_read_register (pnd, PN53X_REG_CIU_FIFOLevel, &sz); if (sz > 0) break; @@ -1335,7 +1453,7 @@ pn53x_initiator_transceive_bits_timed (nfc_device_t * pnd, const byte_t * pbtTx, while (1) { BUFFER_INIT (abtReadRegisterCmd, PN53x_EXTENDED_FRAME__DATA_MAX_LEN); BUFFER_APPEND (abtReadRegisterCmd, ReadRegister); - for (i=0; i> 8); BUFFER_APPEND (abtReadRegisterCmd, PN53X_REG_CIU_FIFOData & 0xff); } @@ -1344,42 +1462,42 @@ pn53x_initiator_transceive_bits_timed (nfc_device_t * pnd, const byte_t * pbtTx, uint8_t abtRes[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szRes = sizeof(abtRes); // Let's send the previously constructed ReadRegister command - if (!pn53x_transceive (pnd, abtReadRegisterCmd, BUFFER_SIZE (abtReadRegisterCmd), abtRes, &szRes, NULL)) { - return false; + if ((res = pn53x_transceive (pnd, abtReadRegisterCmd, BUFFER_SIZE (abtReadRegisterCmd), abtRes, szRes, -1)) < 0) { + return res; } for (i = 0; i < sz; i++) { - pbtRx[i+*pszRxBits] = abtRes[i+off]; + pbtRx[i+szRxBits] = abtRes[i+off]; } - *pszRxBits += (size_t) (sz & SYMBOL_FIFO_LEVEL); + szRxBits += (size_t) (sz & SYMBOL_FIFO_LEVEL); sz = abtRes[sz+off]; if (sz == 0) break; } - *pszRxBits *= 8; // in bits, not bytes + szRxBits *= 8; // in bits, not bytes // Recv corrected timer value *cycles = __pn53x_get_timer (pnd, pbtTx[szTxBits / 8]); - return true; + return szRxBits; } -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) +int +pn53x_initiator_transceive_bytes_timed (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, uint32_t *cycles) { uint16_t i; uint8_t sz; + int res = 0; // We can not just send bytes without parity while the PN53X expects we handled them if (!pnd->bPar) { - pnd->iLastError = EINVALARG; - return false; + pnd->last_error = NFC_EINVARG; + return pnd->last_error; } // Sorry, no easy framing support // TODO to be changed once we'll provide easy framing support from libnfc itself... if (pnd->bEasyFraming) { - pnd->iLastError = ENOTIMPL; - return false; + pnd->last_error = NFC_ENOTIMPL; + return pnd->last_error; } __pn53x_init_timer(pnd, *cycles); @@ -1397,7 +1515,7 @@ pn53x_initiator_transceive_bytes_timed (nfc_device_t * pnd, const byte_t * pbtTx BUFFER_APPEND (abtWriteRegisterCmd, PN53X_REG_CIU_FIFOLevel >> 8); BUFFER_APPEND (abtWriteRegisterCmd, PN53X_REG_CIU_FIFOLevel & 0xff); BUFFER_APPEND (abtWriteRegisterCmd, SYMBOL_FLUSH_BUFFER); - for (i=0; i< szTx; i++) { + for (i = 0; i < szTx; i++) { BUFFER_APPEND (abtWriteRegisterCmd, PN53X_REG_CIU_FIFOData >> 8); BUFFER_APPEND (abtWriteRegisterCmd, PN53X_REG_CIU_FIFOData & 0xff); BUFFER_APPEND (abtWriteRegisterCmd, pbtTx[i]); @@ -1407,17 +1525,17 @@ pn53x_initiator_transceive_bytes_timed (nfc_device_t * pnd, const byte_t * pbtTx BUFFER_APPEND (abtWriteRegisterCmd, PN53X_REG_CIU_BitFraming & 0xff); BUFFER_APPEND (abtWriteRegisterCmd, SYMBOL_START_SEND); // Let's send the previously constructed WriteRegister command - if (!pn53x_transceive (pnd, abtWriteRegisterCmd, BUFFER_SIZE (abtWriteRegisterCmd), NULL, NULL, NULL)) { - return false; + if ((res = pn53x_transceive (pnd, abtWriteRegisterCmd, BUFFER_SIZE (abtWriteRegisterCmd), NULL, 0, -1)) < 0) { + return res; } // Recv data - *pszRx = 0; + size_t szRx = 0; // we've to watch for coming data until we decide to timeout. // our PN53x timer saturates after 4.8ms so this function shouldn't be used for // responses coming very late anyway. // Ideally we should implement a real timer here too but looping a few times is good enough. - for (i=0; i<(3 *(CHIP_DATA (pnd)->timer_prescaler * 2 + 1)); i++) { + for (i = 0; i < (3 *(CHIP_DATA (pnd)->timer_prescaler * 2 + 1)); i++) { pn53x_read_register (pnd, PN53X_REG_CIU_FIFOLevel, &sz); if (sz > 0) break; @@ -1430,7 +1548,7 @@ pn53x_initiator_transceive_bytes_timed (nfc_device_t * pnd, const byte_t * pbtTx while (1) { BUFFER_INIT (abtReadRegisterCmd, PN53x_EXTENDED_FRAME__DATA_MAX_LEN); BUFFER_APPEND (abtReadRegisterCmd, ReadRegister); - for (i=0; i> 8); BUFFER_APPEND (abtReadRegisterCmd, PN53X_REG_CIU_FIFOData & 0xff); } @@ -1439,13 +1557,13 @@ pn53x_initiator_transceive_bytes_timed (nfc_device_t * pnd, const byte_t * pbtTx uint8_t abtRes[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szRes = sizeof(abtRes); // Let's send the previously constructed ReadRegister command - if (!pn53x_transceive (pnd, abtReadRegisterCmd, BUFFER_SIZE (abtReadRegisterCmd), abtRes, &szRes, NULL)) { - return false; + if ((res = pn53x_transceive (pnd, abtReadRegisterCmd, BUFFER_SIZE (abtReadRegisterCmd), abtRes, szRes, -1)) < 0) { + return res; } for (i = 0; i < sz; i++) { - pbtRx[i+*pszRx] = abtRes[i+off]; + pbtRx[i+szRx] = abtRes[i+off]; } - *pszRx += (size_t) (sz & SYMBOL_FIFO_LEVEL); + szRx += (size_t) (sz & SYMBOL_FIFO_LEVEL); sz = abtRes[sz+off]; if (sz == 0) break; @@ -1454,7 +1572,7 @@ pn53x_initiator_transceive_bytes_timed (nfc_device_t * pnd, const byte_t * pbtTx // Recv corrected timer value if (pnd->bCrc) { // We've to compute CRC ourselves to know last byte actually sent - uint8_t * pbtTxRaw; + uint8_t *pbtTxRaw; pbtTxRaw = (uint8_t *) malloc(szTx+2); memcpy (pbtTxRaw, pbtTx, szTx); iso14443a_crc_append (pbtTxRaw, szTx); @@ -1463,37 +1581,38 @@ pn53x_initiator_transceive_bytes_timed (nfc_device_t * pnd, const byte_t * pbtTx } else { *cycles = __pn53x_get_timer (pnd, pbtTx[szTx -1]); } - return true; + return szRx; } -bool -pn53x_initiator_deselect_target (nfc_device_t * pnd) +int +pn53x_initiator_deselect_target (struct nfc_device *pnd) { - return (pn53x_InDeselect (pnd, 0)); // 0 mean deselect all selected targets + return pn53x_InDeselect (pnd, 0); // 0 mean deselect all selected targets } #define SAK_ISO14443_4_COMPLIANT 0x20 #define SAK_ISO18092_COMPLIANT 0x40 -bool -pn53x_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx) +int +pn53x_target_init (struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRxLen, int timeout) { pn53x_reset_settings(pnd); CHIP_DATA (pnd)->operating_mode = TARGET; - pn53x_target_mode_t ptm = PTM_NORMAL; + pn53x_target_mode ptm = PTM_NORMAL; + int res = 0; switch (pnt->nm.nmt) { case NMT_ISO14443A: ptm = PTM_PASSIVE_ONLY; if ((pnt->nti.nai.abtUid[0] != 0x08) || (pnt->nti.nai.szUidLen != 4)) { - pnd->iLastError = ETGUIDNOTSUP; - return false; + pnd->last_error = NFC_EINVARG; + return pnd->last_error; } pn53x_set_parameters (pnd, PARAM_AUTO_ATR_RES, false); if (CHIP_DATA(pnd)->type == PN532) { // We have a PN532 if ((pnt->nti.nai.btSak & SAK_ISO14443_4_COMPLIANT) && (pnd->bAutoIso14443_4)) { - // We have a ISO14443-4 tag to emulate and NDO_AUTO_14443_4A option is enabled + // We have a ISO14443-4 tag to emulate and NP_AUTO_14443_4A option is enabled ptm |= PTM_ISO14443_4_PICC_ONLY; // We add ISO14443-4 restriction pn53x_set_parameters (pnd, PARAM_14443_4_PICC, true); } else { @@ -1516,25 +1635,25 @@ pn53x_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_ case NMT_ISO14443B2SR: case NMT_ISO14443B2CT: case NMT_JEWEL: - pnd->iLastError = EDEVNOTSUP; - return false; + pnd->last_error = NFC_EDEVNOTSUPP; + return pnd->last_error; break; } // Let the PN53X be activated by the RF level detector from power down mode - if (!pn53x_write_register (pnd, PN53X_REG_CIU_TxAuto, SYMBOL_INITIAL_RF_ON, 0x04)) - return false; + if ((res = pn53x_write_register (pnd, PN53X_REG_CIU_TxAuto, SYMBOL_INITIAL_RF_ON, 0x04)) < 0) + return res; - byte_t abtMifareParams[6]; - byte_t * pbtMifareParams = NULL; - byte_t * pbtTkt = NULL; + uint8_t abtMifareParams[6]; + uint8_t *pbtMifareParams = NULL; + uint8_t *pbtTkt = NULL; size_t szTkt = 0; - byte_t abtFeliCaParams[18]; - byte_t * pbtFeliCaParams = NULL; + uint8_t abtFeliCaParams[18]; + uint8_t *pbtFeliCaParams = NULL; - const byte_t * pbtNFCID3t = NULL; - const byte_t * pbtGBt = NULL; + const uint8_t *pbtNFCID3t = NULL; + const uint8_t *pbtGBt = NULL; size_t szGBt = 0; switch(pnt->nm.nmt) { @@ -1618,24 +1737,28 @@ pn53x_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_ case NMT_ISO14443B2SR: case NMT_ISO14443B2CT: case NMT_JEWEL: - pnd->iLastError = EDEVNOTSUP; - return false; + pnd->last_error = NFC_EDEVNOTSUPP; + return pnd->last_error; break; } bool targetActivated = false; + size_t szRx; while (!targetActivated) { - byte_t btActivatedMode; + uint8_t btActivatedMode; - if(!pn53x_TgInitAsTarget(pnd, ptm, pbtMifareParams, pbtTkt, szTkt, pbtFeliCaParams, pbtNFCID3t, pbtGBt, szGBt, pbtRx, pszRx, &btActivatedMode)) { - return false; + if((res = pn53x_TgInitAsTarget(pnd, ptm, pbtMifareParams, pbtTkt, szTkt, pbtFeliCaParams, pbtNFCID3t, pbtGBt, szGBt, pbtRx, szRxLen, &btActivatedMode, timeout)) < 0) { + if (res == NFC_ETIMEOUT) { + return pn53x_idle(pnd); + } + return res; } - - nfc_modulation_t nm = { + szRx = (size_t) res; + nfc_modulation nm = { .nmt = NMT_DEP, // Silent compilation warnings .nbr = NBR_UNDEFINED }; - nfc_dep_mode_t ndm = NDM_UNDEFINED; + nfc_dep_mode ndm = NDM_UNDEFINED; // Decode activated "mode" switch(btActivatedMode & 0x70) { // Baud rate case 0x00: // 106kbps @@ -1681,35 +1804,38 @@ pn53x_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_ if (CHIP_DATA (pnd)->current_target) { free (CHIP_DATA (pnd)->current_target); } - CHIP_DATA (pnd)->current_target = malloc (sizeof(nfc_target_t)); - memcpy (CHIP_DATA (pnd)->current_target, pnt, sizeof(nfc_target_t)); + CHIP_DATA (pnd)->current_target = malloc (sizeof(nfc_target)); + memcpy (CHIP_DATA (pnd)->current_target, pnt, sizeof(nfc_target)); if (ptm & PTM_ISO14443_4_PICC_ONLY) { // When PN532 is in PICC target mode, it automatically reply to RATS so // we don't need to forward this command - *pszRx = 0; + szRx = 0; } } } - return true; + return szRx; } -bool -pn53x_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar) +int +pn53x_target_receive_bits (struct nfc_device *pnd, uint8_t *pbtRx, const size_t szRxLen, uint8_t *pbtRxPar) { - byte_t abtCmd[] = { TgGetInitiatorCommand }; + size_t szRxBits = 0; + uint8_t abtCmd[] = { TgGetInitiatorCommand }; - byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szRx = sizeof (abtRx); + int res = 0; + // Try to gather a received frame from the reader - if (!pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), abtRx, &szRx, NULL)) - return false; - + if ((res = pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), abtRx, szRx, -1)) < 0) + return res; + szRx = (size_t) res; // Get the last bit-count that is stored in the received byte uint8_t ui8rcc; - if (!pn53x_read_register (pnd, PN53X_REG_CIU_Control, &ui8rcc)) - return false; + if ((res = pn53x_read_register (pnd, PN53X_REG_CIU_Control, &ui8rcc)) < 0) + return res; uint8_t ui8Bits = ui8rcc & SYMBOL_RX_LAST_BITS; // Recover the real frame length in bits @@ -1719,21 +1845,26 @@ pn53x_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBit // Check if we should recover the parity bits ourself if (!pnd->bPar) { // Unwrap the response frame - pn53x_unwrap_frame (abtRx + 1, szFrameBits, pbtRx, pszRxBits, pbtRxPar); + if ((res = pn53x_unwrap_frame (abtRx + 1, szFrameBits, pbtRx, pbtRxPar)) < 0) + return res; + szRxBits = res; } else { // Save the received bits - *pszRxBits = szFrameBits; + szRxBits = szFrameBits; + + if ((szRx - 1) > szRxLen) + return NFC_EOVFLOW; // Copy the received bytes memcpy (pbtRx, abtRx + 1, szRx - 1); } - // Everyting seems ok, return true - return true; + // Everyting seems ok, return received bits count + return szRxBits; } -bool -pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout) +int +pn53x_target_receive_bytes (struct nfc_device *pnd, uint8_t *pbtRx, const size_t szRxLen, int timeout) { - byte_t abtCmd[1]; + uint8_t abtCmd[1]; // XXX I think this is not a clean way to provide some kind of "EasyFraming" // but at the moment I have no more better than this @@ -1751,8 +1882,8 @@ pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx, break; } else { // TODO Support EasyFraming for other cases by software - pnd->iLastError = ENOTIMPL; - return false; + pnd->last_error = NFC_ENOTIMPL; + return pnd->last_error; } } default: @@ -1764,33 +1895,40 @@ pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx, } // Try to gather a received frame from the reader - byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; - size_t szRx = sizeof (abtRx); - if (!pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), abtRx, &szRx, timeout)) - return false; + uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + size_t szRx = sizeof (abtRx); + int res = 0; + if ((res = pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), abtRx, szRx, timeout)) < 0) + return pnd->last_error; + szRx = (size_t) res; + // Save the received bytes count + szRx -= 1; - // Save the received byte count - *pszRx = szRx - 1; + if (szRx > szRxLen) + return NFC_EOVFLOW; // Copy the received bytes - memcpy (pbtRx, abtRx + 1, *pszRx); + memcpy (pbtRx, abtRx + 1, szRx); - // Everyting seems ok, return true - return true; + // Everyting seems ok, return received bytes count + return szRx; } -bool -pn53x_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar) +int +pn53x_target_send_bits (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar) { size_t szFrameBits = 0; size_t szFrameBytes = 0; uint8_t ui8Bits = 0; - byte_t abtCmd[PN53x_EXTENDED_FRAME__DATA_MAX_LEN] = { TgResponseToInitiator }; + uint8_t abtCmd[PN53x_EXTENDED_FRAME__DATA_MAX_LEN] = { TgResponseToInitiator }; + int res = 0; // Check if we should prepare the parity bits ourself if (!pnd->bPar) { // Convert data with parity to a frame - pn53x_wrap_frame (pbtTx, szTxBits, pbtTxPar, abtCmd + 1, &szFrameBits); + if ((res = pn53x_wrap_frame (pbtTx, szTxBits, pbtTxPar, abtCmd + 1)) < 0) + return res; + szFrameBits = res; } else { szFrameBits = szTxBits; } @@ -1806,25 +1944,26 @@ pn53x_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t s memcpy (abtCmd + 1, pbtTx, szFrameBytes); // Set the amount of transmission bits in the PN53X chip register - if (!pn53x_set_tx_bits (pnd, ui8Bits)) - return false; + if ((res = pn53x_set_tx_bits (pnd, ui8Bits)) < 0) + return res; // Try to send the bits to the reader - if (!pn53x_transceive (pnd, abtCmd, szFrameBytes + 1, NULL, NULL, NULL)) - return false; + if ((res = pn53x_transceive (pnd, abtCmd, szFrameBytes + 1, NULL, 0, -1)) < 0) + return res; - // Everyting seems ok, return true - return true; + // Everyting seems ok, return return sent bits count + return szTxBits; } -bool -pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, struct timeval *timeout) +int +pn53x_target_send_bytes (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int timeout) { - byte_t abtCmd[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + uint8_t abtCmd[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + int res = 0; // We can not just send bytes without parity if while the PN53X expects we handled them if (!pnd->bPar) - return false; + return NFC_ECHIP; // XXX I think this is not a clean way to provide some kind of "EasyFraming" // but at the moment I have no more better than this @@ -1842,8 +1981,8 @@ pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t break; } else { // TODO Support EasyFraming for other cases by software - pnd->iLastError = ENOTIMPL; - return false; + pnd->last_error = NFC_ENOTIMPL; + return pnd->last_error; } } default: @@ -1856,13 +1995,13 @@ pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t // Copy the data into the command frame memcpy (abtCmd + 1, pbtTx, szTx); - + // Try to send the bits to the reader - if (!pn53x_transceive (pnd, abtCmd, szTx + 1, NULL, NULL, timeout)) - return false; + if ((res = pn53x_transceive (pnd, abtCmd, szTx + 1, NULL, 0, timeout)) < 0) + return res; - // Everyting seems ok, return true - return true; + // Everyting seems ok, return sent byte count + return szTx; } static struct sErrorMessage { @@ -1879,7 +2018,6 @@ static struct sErrorMessage { { EBITCOLL, "Bit-collision" }, // An abnormal bit-collision has been detected during bit wise anti-collision at 106 kbps { ESMALLBUF, "Communication Buffer Too Small" }, // Communication buffer size insufficient { EBUFOVF, "Buffer Overflow" }, // RF Buffer overflow has been detected by the CIU (bit BufferOvfl of the register CIU_Error) - { ERFTIMEOUT, "RF Timeout" }, // In active communication mode, the RF field has not been switched on in time by the counterpart (as defined in NFCIP-1 standard) { ERFPROTO, "RF Protocol Error" }, // RF Protocol error (see PN53x manual) { EOVHEAT, "Chip Overheating" }, // Temperature error: the internal temperature sensor has detected overheating, and therefore has automatically switched off the antenna drivers { EINBUFOVF, "Internal Buffer overflow."}, // Internal buffer overflow @@ -1888,6 +2026,7 @@ static struct sErrorMessage { { ECMD, "Command Not Acceptable" }, // Command is not acceptable due to the current context { EOVCURRENT, "Over Current" }, /* DEP errors */ + { ERFTIMEOUT, "RF Timeout" }, // In active communication mode, the RF field has not been switched on in time by the counterpart (as defined in NFCIP-1 standard) { EDEPUNKCMD, "Unknown DEP Command" }, { EDEPINVSTATE, "Invalid DEP State" }, // DEP Protocol: Invalid device state, the system is in a state which does not allow the operation { ENAD, "NAD Missing in DEP Frame" }, @@ -1901,29 +2040,16 @@ static struct sErrorMessage { { ECID, "Card ID Mismatch" }, // ISO14443 type B: Card ID mismatch, meaning that the expected card has been exchanged with another one. { ECDISCARDED, "Card Discarded" }, // ISO/IEC14443 type B: the card previously activated has disappeared. { ENFCID3, "NFCID3 Mismatch" }, - /* Software level errors */ - { ETGUIDNOTSUP, "Target UID not supported" }, // In target mode, PN53x only support 4 bytes UID and the first byte must start with 0x08 - { EOPABORT, "Operation aborted" }, // Error used to catch a user-requested command abort - { EINVALARG, "Invalid argument" }, // Function called with invalid argument(s) - { ENOTIMPL, "Not (yet) implemented in library" }, - /* Framming-level errors */ - { EFRAACKMISMATCH, "Expected ACK frame" }, - { EFRAISERRFRAME, "Received an error frame" }, - /* Communication-level errors */ - { ECOMIO, "Input/output error" }, // Communication I/O errors: connection broken, read/write failure, unreacheable device, etc. - { ECOMTIMEOUT, "Operation timed-out" }, // A timeout occured while reading device's reply - /* Device-level errors */ - { EDEVNOTSUP, "Operation not supported by device" } // Requested task can not be done by current device }; const char * -pn53x_strerror (const nfc_device_t * pnd) +pn53x_strerror (const struct nfc_device *pnd) { const char *pcRes = "Unknown error"; size_t i; for (i = 0; i < (sizeof (sErrorMessages) / sizeof (struct sErrorMessage)); i++) { - if (sErrorMessages[i].iErrorCode == pnd->iLastError) { + if (sErrorMessages[i].iErrorCode == CHIP_DATA(pnd)->last_status_byte) { pcRes = sErrorMessages[i].pcErrorMsg; break; } @@ -1932,74 +2058,75 @@ pn53x_strerror (const nfc_device_t * pnd) return pcRes; } -bool -pn53x_RFConfiguration__RF_field (nfc_device_t * pnd, bool bEnable) +int +pn53x_RFConfiguration__RF_field (struct nfc_device *pnd, bool bEnable) { - byte_t abtCmd[] = { RFConfiguration, RFCI_FIELD, (bEnable) ? 0x01 : 0x00 }; - return pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL, NULL); + uint8_t abtCmd[] = { RFConfiguration, RFCI_FIELD, (bEnable) ? 0x01 : 0x00 }; + return pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, 0, -1); } -bool -pn53x_RFConfiguration__Various_timings (nfc_device_t * pnd, const uint8_t fATR_RES_Timeout, const uint8_t fRetryTimeout) +int +pn53x_RFConfiguration__Various_timings (struct nfc_device *pnd, const uint8_t fATR_RES_Timeout, const uint8_t fRetryTimeout) { - byte_t abtCmd[] = { + uint8_t abtCmd[] = { RFConfiguration, RFCI_TIMING, 0x00, // RFU fATR_RES_Timeout, // ATR_RES timeout (default: 0x0B 102.4 ms) fRetryTimeout // TimeOut during non-DEP communications (default: 0x0A 51.2 ms) }; - return pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL, NULL); + return pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, 0, -1); } -bool -pn53x_RFConfiguration__MaxRtyCOM (nfc_device_t * pnd, const uint8_t MaxRtyCOM) +int +pn53x_RFConfiguration__MaxRtyCOM (struct nfc_device *pnd, const uint8_t MaxRtyCOM) { - byte_t abtCmd[] = { + uint8_t abtCmd[] = { RFConfiguration, RFCI_RETRY_DATA, MaxRtyCOM // MaxRtyCOM, default: 0x00 (no retry, only one try), inifite: 0xff }; - return pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL, NULL); + return pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, 0, -1); } -bool -pn53x_RFConfiguration__MaxRetries (nfc_device_t * pnd, const uint8_t MxRtyATR, const uint8_t MxRtyPSL, const uint8_t MxRtyPassiveActivation) +int +pn53x_RFConfiguration__MaxRetries (struct nfc_device *pnd, const uint8_t MxRtyATR, const uint8_t MxRtyPSL, const uint8_t MxRtyPassiveActivation) { // Retry format: 0x00 means only 1 try, 0xff means infinite - byte_t abtCmd[] = { + uint8_t abtCmd[] = { RFConfiguration, RFCI_RETRY_SELECT, MxRtyATR, // MxRtyATR, default: active = 0xff, passive = 0x02 MxRtyPSL, // MxRtyPSL, default: 0x01 MxRtyPassiveActivation // MxRtyPassiveActivation, default: 0xff (0x00 leads to problems with PN531) }; - return pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL, NULL); + return pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, 0, -1); } -bool -pn53x_SetParameters (nfc_device_t * pnd, const uint8_t ui8Value) +int +pn53x_SetParameters (struct nfc_device *pnd, const uint8_t ui8Value) { - byte_t abtCmd[] = { SetParameters, ui8Value }; + uint8_t abtCmd[] = { SetParameters, ui8Value }; + int res = 0; - if(!pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL, NULL)) { - return false; + if((res = pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, 0, -1)) < 0) { + return res; } // We save last parameters in register cache CHIP_DATA (pnd)->ui8Parameters = ui8Value; - return true; + return NFC_SUCCESS; } -bool -pn53x_SAMConfiguration (nfc_device_t * pnd, const pn532_sam_mode ui8Mode, struct timeval *timeout) +int +pn53x_SAMConfiguration (struct nfc_device *pnd, const pn532_sam_mode ui8Mode, int timeout) { - byte_t abtCmd[] = { SAMConfiguration, ui8Mode, 0x00, 0x00 }; + uint8_t abtCmd[] = { SAMConfiguration, ui8Mode, 0x00, 0x00 }; size_t szCmd = sizeof(abtCmd); if (CHIP_DATA(pnd)->type != PN532) { // This function is not supported by pn531 neither pn533 - pnd->iLastError = EDEVNOTSUP; - return false; + pnd->last_error = NFC_EDEVNOTSUPP; + return pnd->last_error; } switch (ui8Mode) { @@ -2013,24 +2140,24 @@ pn53x_SAMConfiguration (nfc_device_t * pnd, const pn532_sam_mode ui8Mode, struct szCmd = 3; break; default: - pnd->iLastError = EINVALARG; - return false; + pnd->last_error = NFC_EINVARG; + return pnd->last_error; } - return (pn53x_transceive (pnd, abtCmd, szCmd, NULL, NULL, timeout)); + return (pn53x_transceive (pnd, abtCmd, szCmd, NULL, 0, timeout)); } -bool -pn53x_PowerDown (nfc_device_t * pnd) +int +pn53x_PowerDown (struct nfc_device *pnd) { - byte_t abtCmd[] = { PowerDown, 0xf0 }; - return (pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL, NULL)); + uint8_t abtCmd[] = { PowerDown, 0xf0 }; + return (pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, 0, -1)); } /** * @brief C wrapper to InListPassiveTarget command - * @return true if command is successfully sent + * @return Returns selected targets count on success, otherwise returns libnfc's error code (negative value) * - * @param pnd nfc_device_t struct pointer that represent currently used device + * @param pnd struct nfc_device struct pointer that represent currently used device * @param pmInitModulation Desired modulation * @param pbtInitiatorData Optional initiator data used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID * @param szInitiatorData Length of initiator data \a pbtInitiatorData @@ -2040,14 +2167,14 @@ pn53x_PowerDown (nfc_device_t * pnd) * @note Selected targets count can be found in \a pbtTargetsData[0] if available (i.e. \a pszTargetsData content is more than 0) * @note To decode theses TargetData[n], there is @fn pn53x_decode_target_data */ -bool -pn53x_InListPassiveTarget (nfc_device_t * pnd, - const pn53x_modulation_t pmInitModulation, const byte_t szMaxTargets, - const byte_t * pbtInitiatorData, const size_t szInitiatorData, - byte_t * pbtTargetsData, size_t * pszTargetsData, - struct timeval* timeout) +int +pn53x_InListPassiveTarget (struct nfc_device *pnd, + const pn53x_modulation pmInitModulation, const uint8_t szMaxTargets, + const uint8_t *pbtInitiatorData, const size_t szInitiatorData, + uint8_t *pbtTargetsData, size_t *pszTargetsData, + int timeout) { - byte_t abtCmd[15] = { InListPassiveTarget }; + uint8_t abtCmd[15] = { InListPassiveTarget }; abtCmd[1] = szMaxTargets; // MaxTg @@ -2060,15 +2187,15 @@ pn53x_InListPassiveTarget (nfc_device_t * pnd, case PM_ISO14443B_106: if (!(pnd->btSupportByte & SUPPORT_ISO14443B)) { // Eg. Some PN532 doesn't support type B! - pnd->iLastError = EDEVNOTSUP; - return false; + pnd->last_error = NFC_EDEVNOTSUPP; + return pnd->last_error; } break; case PM_JEWEL_106: if(CHIP_DATA(pnd)->type == PN531) { // These modulations are not supported by pn531 - pnd->iLastError = EDEVNOTSUP; - return false; + pnd->last_error = NFC_EDEVNOTSUPP; + return pnd->last_error; } break; case PM_ISO14443B_212: @@ -2076,103 +2203,114 @@ pn53x_InListPassiveTarget (nfc_device_t * pnd, case PM_ISO14443B_847: if((CHIP_DATA(pnd)->type != PN533) || (!(pnd->btSupportByte & SUPPORT_ISO14443B))) { // These modulations are not supported by pn531 neither pn532 - pnd->iLastError = EDEVNOTSUP; - return false; + pnd->last_error = NFC_EDEVNOTSUPP; + return pnd->last_error; } break; default: - pnd->iLastError = EINVALARG; - return false; + pnd->last_error = NFC_EINVARG; + return pnd->last_error; } abtCmd[2] = pmInitModulation; // BrTy, the type of init modulation used for polling a passive tag // Set the optional initiator data (used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID). if (pbtInitiatorData) memcpy (abtCmd + 3, pbtInitiatorData, szInitiatorData); - - return pn53x_transceive (pnd, abtCmd, 3 + szInitiatorData, pbtTargetsData, pszTargetsData, timeout); + int res = 0; + if ((res = pn53x_transceive (pnd, abtCmd, 3 + szInitiatorData, pbtTargetsData, *pszTargetsData, timeout)) < 0) { + return res; + } + *pszTargetsData = (size_t) res; + return pbtTargetsData[0]; } -bool -pn53x_InDeselect (nfc_device_t * pnd, const uint8_t ui8Target) +int +pn53x_InDeselect (struct nfc_device *pnd, const uint8_t ui8Target) { if (CHIP_DATA(pnd)->type == RCS360) { // We should do act here *only* if a target was previously selected - byte_t abtStatus[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + uint8_t abtStatus[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szStatus = sizeof(abtStatus); - byte_t abtCmdGetStatus[] = { GetGeneralStatus }; - if (!pn53x_transceive (pnd, abtCmdGetStatus, sizeof (abtCmdGetStatus), abtStatus, &szStatus, NULL)) { - return false; + uint8_t abtCmdGetStatus[] = { GetGeneralStatus }; + int res = 0; + if ((res = pn53x_transceive (pnd, abtCmdGetStatus, sizeof (abtCmdGetStatus), abtStatus, szStatus, -1)) < 0) { + return res; } + szStatus = (size_t) res; if ((szStatus < 3) || (abtStatus[2] == 0)) { - return true; + return NFC_SUCCESS; } // No much choice what to deselect actually... - byte_t abtCmdRcs360[] = { InDeselect, 0x01, 0x01 }; - return (pn53x_transceive (pnd, abtCmdRcs360, sizeof (abtCmdRcs360), NULL, NULL, NULL)); + uint8_t abtCmdRcs360[] = { InDeselect, 0x01, 0x01 }; + return (pn53x_transceive (pnd, abtCmdRcs360, sizeof (abtCmdRcs360), NULL, 0, -1)); } - byte_t abtCmd[] = { InDeselect, ui8Target }; - return (pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL, NULL)); + uint8_t abtCmd[] = { InDeselect, ui8Target }; + return (pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, 0, -1)); } -bool -pn53x_InRelease (nfc_device_t * pnd, const uint8_t ui8Target) +int +pn53x_InRelease (struct nfc_device *pnd, const uint8_t ui8Target) { if (CHIP_DATA(pnd)->type == RCS360) { // We should do act here *only* if a target was previously selected - byte_t abtStatus[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + uint8_t abtStatus[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szStatus = sizeof(abtStatus); - byte_t abtCmdGetStatus[] = { GetGeneralStatus }; - if (!pn53x_transceive (pnd, abtCmdGetStatus, sizeof (abtCmdGetStatus), abtStatus, &szStatus, NULL)) { - return false; + uint8_t abtCmdGetStatus[] = { GetGeneralStatus }; + int res = 0; + if ((res = pn53x_transceive (pnd, abtCmdGetStatus, sizeof (abtCmdGetStatus), abtStatus, szStatus, -1)) < 0) { + return res; } + szStatus = (size_t) res; if ((szStatus < 3) || (abtStatus[2] == 0)) { - return true; + return NFC_SUCCESS; } // No much choice what to release actually... - byte_t abtCmdRcs360[] = { InRelease, 0x01, 0x01 }; - return (pn53x_transceive (pnd, abtCmdRcs360, sizeof (abtCmdRcs360), NULL, NULL, NULL)); + uint8_t abtCmdRcs360[] = { InRelease, 0x01, 0x01 }; + return (pn53x_transceive (pnd, abtCmdRcs360, sizeof (abtCmdRcs360), NULL, 0, -1)); } - byte_t abtCmd[] = { InRelease, ui8Target }; - return (pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, NULL, NULL)); + uint8_t abtCmd[] = { InRelease, ui8Target }; + return (pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), NULL, 0, -1)); } -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) +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) { + size_t szTargetFound = 0; if (CHIP_DATA(pnd)->type != PN532) { // This function is not supported by pn531 neither pn533 - pnd->iLastError = EDEVNOTSUP; - return false; + pnd->last_error = NFC_EDEVNOTSUPP; + return pnd->last_error; } // InAutoPoll frame looks like this { 0xd4, 0x60, 0x0f, 0x01, 0x00 } => { direction, command, pollnr, period, types... } size_t szTxInAutoPoll = 3 + szTargetTypes; - byte_t abtCmd[3+15] = { InAutoPoll, btPollNr, btPeriod }; + uint8_t abtCmd[3+15] = { InAutoPoll, btPollNr, btPeriod }; for (size_t n = 0; n < szTargetTypes; n++) { abtCmd[3 + n] = ppttTargetTypes[n]; } - byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szRx = sizeof(abtRx); - bool res = pn53x_transceive (pnd, abtCmd, szTxInAutoPoll, abtRx, &szRx, NULL); - - if (res == false) { - return false; + int res = pn53x_transceive (pnd, abtCmd, szTxInAutoPoll, abtRx, szRx, timeout); +szRx = (size_t) res; + if (res < 0) { + return res; } else if (szRx > 0) { - *pszTargetFound = abtRx[0]; - if (*pszTargetFound) { + szTargetFound = abtRx[0]; + if (szTargetFound > 0) { uint8_t ln; - byte_t *pbt = abtRx + 1; + uint8_t *pbt = abtRx + 1; /* 1st target */ // Target type - pn53x_target_type_t ptt = *(pbt++); + pn53x_target_type ptt = *(pbt++); pntTargets[0].nm = pn53x_ptt_to_nm(ptt); // AutoPollTargetData length ln = *(pbt++); - pn53x_decode_target_data (pbt, ln, CHIP_DATA(pnd)->type, pntTargets[0].nm.nmt, &(pntTargets[0].nti)); + if ((res = pn53x_decode_target_data (pbt, ln, CHIP_DATA(pnd)->type, pntTargets[0].nm.nmt, &(pntTargets[0].nti))) < 0) { + return res; + } pbt += ln; if (abtRx[0] > 1) { @@ -2186,7 +2324,7 @@ pn53x_InAutoPoll (nfc_device_t * pnd, } } } - return true; + return szTargetFound; } /** @@ -2197,19 +2335,20 @@ pn53x_InAutoPoll (nfc_device_t * pnd, * @param pbtNFCID3i NFCID3 of the initiator * @param pbtGBi General Bytes of the initiator * @param szGBi count of General Bytes - * @param[out] pnt \a nfc_target_t which will be filled by this function + * @param[out] pnt \a nfc_target which will be filled by this function */ -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 * pbtGBi, const size_t szGBi, - nfc_target_t * pnt) +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 *pbtGBi, const size_t szGBi, + nfc_target *pnt, + const int timeout) { // Max frame size = 1 (Command) + 1 (ActPass) + 1 (Baud rate) + 1 (Next) + 5 (PassiveInitiatorData) + 10 (NFCID3) + 48 (General bytes) = 67 bytes - byte_t abtCmd[67] = { InJumpForDEP, (ndm == NDM_ACTIVE) ? 0x01 : 0x00 }; + uint8_t abtCmd[67] = { InJumpForDEP, (ndm == NDM_ACTIVE) ? 0x01 : 0x00 }; size_t offset = 4; // 1 byte for command, 1 byte for DEP mode (Active/Passive), 1 byte for baud rate, 1 byte for following parameters flag @@ -2225,8 +2364,8 @@ pn53x_InJumpForDEP (nfc_device_t * pnd, break; case NBR_847: case NBR_UNDEFINED: - pnd->iLastError = EINVALARG; - return false; + pnd->last_error = NFC_EINVARG; + return pnd->last_error; break; } @@ -2245,8 +2384,8 @@ pn53x_InJumpForDEP (nfc_device_t * pnd, break; case NBR_847: case NBR_UNDEFINED: - pnd->iLastError = EINVALARG; - return false; + pnd->last_error = NFC_EINVARG; + return pnd->last_error; break; } } @@ -2263,46 +2402,48 @@ pn53x_InJumpForDEP (nfc_device_t * pnd, offset += szGBi; } - byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szRx = sizeof (abtRx); + int res = 0; // Try to find a target, call the transceive callback function of the current device - if (!pn53x_transceive (pnd, abtCmd, offset, abtRx, &szRx, NULL)) - return false; - + if ((res = pn53x_transceive (pnd, abtCmd, offset, abtRx, szRx, timeout)) < 0) + return res; + szRx = (size_t) res; // Make sure one target has been found, the PN53X returns 0x00 if none was available - if (abtRx[1] != 1) - return false; - - // Is a target struct available - if (pnt) { - pnt->nm.nmt = NMT_DEP; - pnt->nm.nbr = nbr; - memcpy (pnt->nti.ndi.abtNFCID3, abtRx + 2, 10); - pnt->nti.ndi.btDID = abtRx[12]; - pnt->nti.ndi.btBS = abtRx[13]; - pnt->nti.ndi.btBR = abtRx[14]; - pnt->nti.ndi.btTO = abtRx[15]; - pnt->nti.ndi.btPP = abtRx[16]; - if(szRx > 17) { - pnt->nti.ndi.szGB = szRx - 17; - memcpy (pnt->nti.ndi.abtGB, abtRx + 17, pnt->nti.ndi.szGB); - } else { - pnt->nti.ndi.szGB = 0; + if (abtRx[1] >= 1) { + // Is a target struct available + if (pnt) { + pnt->nm.nmt = NMT_DEP; + pnt->nm.nbr = nbr; + pnt->nti.ndi.ndm = ndm; + memcpy (pnt->nti.ndi.abtNFCID3, abtRx + 2, 10); + pnt->nti.ndi.btDID = abtRx[12]; + pnt->nti.ndi.btBS = abtRx[13]; + pnt->nti.ndi.btBR = abtRx[14]; + pnt->nti.ndi.btTO = abtRx[15]; + pnt->nti.ndi.btPP = abtRx[16]; + if(szRx > 17) { + pnt->nti.ndi.szGB = szRx - 17; + memcpy (pnt->nti.ndi.abtGB, abtRx + 17, pnt->nti.ndi.szGB); + } else { + pnt->nti.ndi.szGB = 0; + } } } - return true; + return abtRx[1]; } -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 * pbtGBt, const size_t szGBt, - byte_t * pbtRx, size_t * pszRx, byte_t * pbtModeByte) +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 *pbtGBt, const size_t szGBt, + uint8_t *pbtRx, const size_t szRxLen, uint8_t *pbtModeByte, int timeout) { - byte_t abtCmd[39 + 47 + 48] = { TgInitAsTarget }; // Worst case: 39-byte base, 47 bytes max. for General Bytes, 48 bytes max. for Historical Bytes + uint8_t abtCmd[39 + 47 + 48] = { TgInitAsTarget }; // Worst case: 39-byte base, 47 bytes max. for General Bytes, 48 bytes max. for Historical Bytes size_t szOptionalBytes = 0; + int res = 0; // Clear the target init struct, reset to all zeros memset (abtCmd + 1, 0x00, sizeof (abtCmd) - 1); @@ -2329,7 +2470,7 @@ pn53x_TgInitAsTarget (nfc_device_t * pnd, pn53x_target_mode_t ptm, szOptionalBytes = szGBt; } } else { - abtCmd[36] = (byte_t)(szGBt); + abtCmd[36] = (uint8_t)(szGBt); if (szGBt) { memcpy (abtCmd+37, pbtGBt, szGBt); } @@ -2337,7 +2478,7 @@ pn53x_TgInitAsTarget (nfc_device_t * pnd, pn53x_target_mode_t ptm, } // Historical bytes (ISO/IEC 14443-4) if ((CHIP_DATA(pnd)->type != PN531) && (CHIP_DATA(pnd)->type != RCS360)) { // PN531 does not handle Historical Bytes - abtCmd[36+szOptionalBytes] = (byte_t)(szTkt); + abtCmd[36+szOptionalBytes] = (uint8_t)(szTkt); if (szTkt) { memcpy (abtCmd+37+szOptionalBytes, pbtTkt, szTkt); } @@ -2345,10 +2486,11 @@ pn53x_TgInitAsTarget (nfc_device_t * pnd, pn53x_target_mode_t ptm, } // Request the initialization as a target - byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; + uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; size_t szRx = sizeof (abtRx); - if (!pn53x_transceive (pnd, abtCmd, 36 + szOptionalBytes, abtRx, &szRx, NULL)) - return false; + if ((res = pn53x_transceive (pnd, abtCmd, 36 + szOptionalBytes, abtRx, szRx, timeout)) < 0) + return res; + szRx = (size_t) res; // Note: the first byte is skip: // its the "mode" byte which contains baudrate, DEP and Framing type (Mifare, active or FeliCa) datas. @@ -2357,38 +2499,41 @@ pn53x_TgInitAsTarget (nfc_device_t * pnd, pn53x_target_mode_t ptm, } // Save the received byte count - *pszRx = szRx - 1; + szRx -= 1; + + if ((szRx - 1) > szRxLen) + return NFC_EOVFLOW; // Copy the received bytes - memcpy (pbtRx, abtRx + 1, *pszRx); + memcpy (pbtRx, abtRx + 1, szRx); - return true; + return szRx; } -bool -pn53x_check_ack_frame (nfc_device_t * pnd, const byte_t * pbtRxFrame, const size_t szRxFrameLen) +int +pn53x_check_ack_frame (struct nfc_device *pnd, const uint8_t *pbtRxFrame, const size_t szRxFrameLen) { if (szRxFrameLen >= sizeof (pn53x_ack_frame)) { if (0 == memcmp (pbtRxFrame, pn53x_ack_frame, sizeof (pn53x_ack_frame))) { log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "PN53x ACKed"); - return true; + return NFC_SUCCESS; } } - pnd->iLastError = EFRAACKMISMATCH; + pnd->last_error = NFC_EIO; log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unexpected PN53x reply!"); - return false; + return pnd->last_error; } -bool -pn53x_check_error_frame (nfc_device_t * pnd, const byte_t * pbtRxFrame, const size_t szRxFrameLen) +int +pn53x_check_error_frame (struct nfc_device *pnd, const uint8_t *pbtRxFrame, const size_t szRxFrameLen) { if (szRxFrameLen >= sizeof (pn53x_error_frame)) { if (0 == memcmp (pbtRxFrame, pn53x_error_frame, sizeof (pn53x_error_frame))) { log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "PN53x sent an error frame"); - pnd->iLastError = EFRAISERRFRAME; - return false; + pnd->last_error = NFC_EIO; + return pnd->last_error; } } - return true; + return NFC_SUCCESS; } /** @@ -2397,8 +2542,8 @@ pn53x_check_error_frame (nfc_device_t * pnd, const byte_t * pbtRxFrame, const si * @param pbtData payload (bytes array) of the frame, will become PD0, ..., PDn in PN53x frame * @note The first byte of pbtData is the Command Code (CC) */ -bool -pn53x_build_frame (byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData) +int +pn53x_build_frame (uint8_t *pbtFrame, size_t *pszFrame, const uint8_t *pbtData, const size_t szData) { if (szData <= PN53x_NORMAL_FRAME__DATA_MAX_LEN) { // LEN - Packet length = data length (len) + checksum (1) + end of stream marker (1) @@ -2411,7 +2556,7 @@ pn53x_build_frame (byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, memcpy (pbtFrame + 6, pbtData, szData); // DCS - Calculate data payload checksum - byte_t btDCS = (256 - 0xD4); + uint8_t btDCS = (256 - 0xD4); for (size_t szPos = 0; szPos < szData; szPos++) { btDCS -= pbtData[szPos]; } @@ -2437,7 +2582,7 @@ pn53x_build_frame (byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, memcpy (pbtFrame + 9, pbtData, szData); // DCS - Calculate data payload checksum - byte_t btDCS = (256 - 0xD4); + uint8_t btDCS = (256 - 0xD4); for (size_t szPos = 0; szPos < szData; szPos++) { btDCS -= pbtData[szPos]; } @@ -2449,12 +2594,12 @@ pn53x_build_frame (byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, (*pszFrame) = szData + PN53x_EXTENDED_FRAME__OVERHEAD; } else { log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "We can't send more than %d bytes in a raw (requested: %zd)", PN53x_EXTENDED_FRAME__DATA_MAX_LEN, szData); - return false; + return NFC_ECHIP; } - return true; + return NFC_SUCCESS; } -pn53x_modulation_t -pn53x_nm_to_pm(const nfc_modulation_t nm) +pn53x_modulation +pn53x_nm_to_pm(const nfc_modulation nm) { switch(nm.nmt) { case NMT_ISO14443A: @@ -2511,8 +2656,8 @@ pn53x_nm_to_pm(const nfc_modulation_t nm) return PM_UNDEFINED; } -nfc_modulation_t -pn53x_ptt_to_nm( const pn53x_target_type_t ptt ) +nfc_modulation +pn53x_ptt_to_nm( const pn53x_target_type ptt ) { switch (ptt) { case PTT_GENERIC_PASSIVE_106: @@ -2524,44 +2669,44 @@ pn53x_ptt_to_nm( const pn53x_target_type_t ptt ) case PTT_MIFARE: case PTT_ISO14443_4A_106: - return (const nfc_modulation_t){ .nmt = NMT_ISO14443A, .nbr = NBR_106 }; + return (const nfc_modulation){ .nmt = NMT_ISO14443A, .nbr = NBR_106 }; break; case PTT_ISO14443_4B_106: case PTT_ISO14443_4B_TCL_106: - return (const nfc_modulation_t){ .nmt = NMT_ISO14443B, .nbr = NBR_106 }; + return (const nfc_modulation){ .nmt = NMT_ISO14443B, .nbr = NBR_106 }; break; case PTT_JEWEL_106: - return (const nfc_modulation_t){ .nmt = NMT_JEWEL, .nbr = NBR_106 }; + return (const nfc_modulation){ .nmt = NMT_JEWEL, .nbr = NBR_106 }; break; case PTT_FELICA_212: - return (const nfc_modulation_t){ .nmt = NMT_FELICA, .nbr = NBR_212 }; + return (const nfc_modulation){ .nmt = NMT_FELICA, .nbr = NBR_212 }; break; case PTT_FELICA_424: - return (const nfc_modulation_t){ .nmt = NMT_FELICA, .nbr = NBR_424 }; + return (const nfc_modulation){ .nmt = NMT_FELICA, .nbr = NBR_424 }; break; case PTT_DEP_PASSIVE_106: case PTT_DEP_ACTIVE_106: - return (const nfc_modulation_t){ .nmt = NMT_DEP, .nbr = NBR_106 }; + return (const nfc_modulation){ .nmt = NMT_DEP, .nbr = NBR_106 }; break; case PTT_DEP_PASSIVE_212: case PTT_DEP_ACTIVE_212: - return (const nfc_modulation_t){ .nmt = NMT_DEP, .nbr = NBR_212 }; + return (const nfc_modulation){ .nmt = NMT_DEP, .nbr = NBR_212 }; break; case PTT_DEP_PASSIVE_424: case PTT_DEP_ACTIVE_424: - return (const nfc_modulation_t){ .nmt = NMT_DEP, .nbr = NBR_424 }; + return (const nfc_modulation){ .nmt = NMT_DEP, .nbr = NBR_424 }; break; } // We should never be here, this line silent compilation warning - return (const nfc_modulation_t){ .nmt = NMT_ISO14443A, .nbr = NBR_106 }; + return (const nfc_modulation){ .nmt = NMT_ISO14443A, .nbr = NBR_106 }; } -pn53x_target_type_t -pn53x_nm_to_ptt(const nfc_modulation_t nm) +pn53x_target_type +pn53x_nm_to_ptt(const nfc_modulation nm) { switch(nm.nmt) { case NMT_ISO14443A: @@ -2614,7 +2759,7 @@ pn53x_nm_to_ptt(const nfc_modulation_t nm) } void -pn53x_data_new (nfc_device_t * pnd, const struct pn53x_io* io) +pn53x_data_new (struct nfc_device *pnd, const struct pn53x_io *io) { pnd->chip_data = malloc(sizeof(struct pn53x_data)); @@ -2631,16 +2776,28 @@ pn53x_data_new (nfc_device_t * pnd, const struct pn53x_io* io) // PN53x starts in initiator mode CHIP_DATA (pnd)->operating_mode = INITIATOR; + // Clear last status byte + CHIP_DATA (pnd)->last_status_byte = 0x00; + // Set current target to NULL CHIP_DATA (pnd)->current_target = NULL; // WriteBack cache is clean CHIP_DATA (pnd)->wb_trigged = false; memset (CHIP_DATA (pnd)->wb_mask, 0x00, PN53X_CACHE_REGISTER_SIZE); + + // Set default command timeout (250 ms) + CHIP_DATA (pnd)->timeout_command = 250; + + // Set default ATR timeout (103 ms) + CHIP_DATA (pnd)->timeout_atr = 103; + + // Set default communication timeout (52 ms) + CHIP_DATA (pnd)->timeout_communication = 52; } void -pn53x_data_free (nfc_device_t * pnd) +pn53x_data_free (struct nfc_device *pnd) { if (CHIP_DATA (pnd)->current_target) { free (CHIP_DATA (pnd)->current_target); diff --git a/libnfc/chips/pn53x.h b/libnfc/chips/pn53x.h index 9f32b6f..998506a 100644 --- a/libnfc/chips/pn53x.h +++ b/libnfc/chips/pn53x.h @@ -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__ diff --git a/libnfc/drivers.h b/libnfc/drivers.h index 2671db4..694b160 100644 --- a/libnfc/drivers.h +++ b/libnfc/drivers.h @@ -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__ diff --git a/libnfc/drivers/Makefile.am b/libnfc/drivers/Makefile.am index d95a952..edfef5f 100644 --- a/libnfc/drivers/Makefile.am +++ b/libnfc/drivers/Makefile.am @@ -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 - diff --git a/libnfc/drivers/acr122.c b/libnfc/drivers/acr122.c index 0732275..2acfaf8 100644 --- a/libnfc/drivers/acr122.c +++ b/libnfc/drivers/acr122.c @@ -26,6 +26,7 @@ # include "config.h" #endif // HAVE_CONFIG_H +#include #include #include #include @@ -40,7 +41,7 @@ // Bus #include -# 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 }; diff --git a/libnfc/drivers/acr122.h b/libnfc/drivers/acr122.h index db05e2f..5c2ba98 100644 --- a/libnfc/drivers/acr122.h +++ b/libnfc/drivers/acr122.h @@ -26,14 +26,14 @@ # include -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__ diff --git a/libnfc/drivers/acr122s.c b/libnfc/drivers/acr122s.c index 225a0c9..4f2b2ff 100644 --- a/libnfc/drivers/acr122s.c +++ b/libnfc/drivers/acr122s.c @@ -29,6 +29,9 @@ #include "acr122s.h" #include +#include +#include +#include #include #include @@ -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, diff --git a/libnfc/drivers/acr122s.h b/libnfc/drivers/acr122s.h index f81b07d..60fcbab 100644 --- a/libnfc/drivers/acr122s.h +++ b/libnfc/drivers/acr122s.h @@ -28,14 +28,14 @@ #include #include -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 diff --git a/libnfc/drivers/arygon.c b/libnfc/drivers/arygon.c index 537ff29..56fd340 100644 --- a/libnfc/drivers/arygon.c +++ b/libnfc/drivers/arygon.c @@ -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 +#include #include #include #include @@ -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() }; diff --git a/libnfc/drivers/arygon.h b/libnfc/drivers/arygon.h index 11318b8..711a9c1 100644 --- a/libnfc/drivers/arygon.h +++ b/libnfc/drivers/arygon.h @@ -30,14 +30,14 @@ # include -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__ diff --git a/libnfc/drivers/pn532_uart.c b/libnfc/drivers/pn532_uart.c index 83c2a80..19d3efc 100644 --- a/libnfc/drivers/pn532_uart.c +++ b/libnfc/drivers/pn532_uart.c @@ -32,6 +32,7 @@ #include "pn532_uart.h" #include +#include #include #include @@ -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, diff --git a/libnfc/drivers/pn532_uart.h b/libnfc/drivers/pn532_uart.h index 5ecb21c..c066e75 100644 --- a/libnfc/drivers/pn532_uart.h +++ b/libnfc/drivers/pn532_uart.h @@ -29,13 +29,13 @@ # include -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__ diff --git a/libnfc/drivers/pn53x_usb.c b/libnfc/drivers/pn53x_usb.c index f4f3e81..75f90fc 100644 --- a/libnfc/drivers/pn53x_usb.c +++ b/libnfc/drivers/pn53x_usb.c @@ -32,10 +32,11 @@ Thanks to d18c7db and Okko for example code */ -#include -#include #include #include +#include +#include +#include #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, diff --git a/libnfc/drivers/pn53x_usb.h b/libnfc/drivers/pn53x_usb.h index b2bff4c..566f0bb 100644 --- a/libnfc/drivers/pn53x_usb.h +++ b/libnfc/drivers/pn53x_usb.h @@ -23,18 +23,20 @@ */ #ifndef __NFC_DRIVER_PN53X_USB_H__ -# define __NFC_DRIVER_PN53X_USB_H__ +#define __NFC_DRIVER_PN53X_USB_H__ -# include +#include -# include +#include -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__ diff --git a/libnfc/iso14443-subr.c b/libnfc/iso14443-subr.c index 97afbd1..ec0e002 100644 --- a/libnfc/iso14443-subr.c +++ b/libnfc/iso14443-subr.c @@ -32,30 +32,30 @@ #include 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: diff --git a/libnfc/log.c b/libnfc/log-printf.c similarity index 75% rename from libnfc/log.c rename to libnfc/log-printf.c index 0e40f07..f440f79 100644 --- a/libnfc/log.c +++ b/libnfc/log-printf.c @@ -17,9 +17,10 @@ #include "config.h" +#include +#include +#include #include -#include -#include #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); } diff --git a/libnfc/log.h b/libnfc/log.h index a5f3565..6a41a07 100644 --- a/libnfc/log.h +++ b/libnfc/log.h @@ -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 - -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 diff --git a/libnfc/mirror-subr.c b/libnfc/mirror-subr.c index 7b5953b..361038f 100644 --- a/libnfc/mirror-subr.c +++ b/libnfc/mirror-subr.c @@ -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; } diff --git a/libnfc/mirror-subr.h b/libnfc/mirror-subr.h index c795f7e..081bc88 100644 --- a/libnfc/mirror-subr.h +++ b/libnfc/mirror-subr.h @@ -29,9 +29,9 @@ # include -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_ diff --git a/libnfc/nfc-device.c b/libnfc/nfc-device.c index 7cd5cb6..b19dec6 100644 --- a/libnfc/nfc-device.c +++ b/libnfc/nfc-device.c @@ -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 +#include #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); diff --git a/libnfc/nfc-emulation.c b/libnfc/nfc-emulation.c index 264f651..d952fc5 100644 --- a/libnfc/nfc-emulation.c +++ b/libnfc/nfc-emulation.c @@ -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; } } diff --git a/libnfc/nfc-internal.c b/libnfc/nfc-internal.c index 36da205..6f84d84 100644 --- a/libnfc/nfc-internal.c +++ b/libnfc/nfc-internal.c @@ -23,39 +23,38 @@ */ #include -#include 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; diff --git a/libnfc/nfc-internal.h b/libnfc/nfc-internal.h index 45f478e..dfe8107 100644 --- a/libnfc/nfc-internal.h +++ b/libnfc/nfc-internal.h @@ -23,24 +23,25 @@ */ #ifndef __NFC_INTERNAL_H__ -# define __NFC_INTERNAL_H__ +#define __NFC_INTERNAL_H__ -# include -# include -# include +#include +#include # include +#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__ diff --git a/libnfc/nfc.c b/libnfc/nfc.c index ac67099..5105672 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -45,7 +45,7 @@ #define LOG_CATEGORY "libnfc.general" -const struct nfc_driver_t *nfc_drivers[] = { +const struct nfc_driver *nfc_drivers[] = { # if defined (DRIVER_PN53X_USB_ENABLED) &pn53x_usb_driver, # endif /* DRIVER_PN53X_USB_ENABLED */ @@ -65,197 +65,271 @@ const struct nfc_driver_t *nfc_drivers[] = { }; /** - * @brief Connect to a NFC device - * @param pndd device description if specific device is wanted, \c NULL otherwise - * @return Returns pointer to a \a nfc_device_t struct if successfull; otherwise returns \c NULL value. + * @brief Initialize libnfc. + * This function must be called before calling any other libnfc function + * @param context Optional output location for context pointer + */ +void +nfc_init(nfc_context *context) +{ + log_init (); +} + +/** + * @brief Deinitialize libnfc. + * Should be called after closing all open devices and before your application terminates. + *@param context The context to deinitialize + */ +void +nfc_exit(nfc_context *context) +{ + log_fini (); +} + +/** + * @brief Get the defaut NFC device + * @param connstring \a nfc_connstring pointer where the default connection string will be stored + * @return \e true on success * - * If \e pndd is \c NULL, the first available NFC device is claimed. - * It will automatically search the system using all available drivers to determine a device is NFC-enabled. + * This function fill \e connstring with the LIBNFC_DEFAULT_DEVICE environment variable content + * if is set otherwise it will search for the first available device, and fill + * \e connstring with the corresponding \a nfc_connstring value. * - * If \e pndd is passed then this function will try to claim the right device using information provided by the \a nfc_device_desc_t struct. + * This function returns true when LIBNFC_DEFAULT_DEVICE is set or an available device is found. + * + * @note The \e connstring content can be invalid if LIBNFC_DEFAULT_DEVICE is + * set with incorrect value. + */ +bool +nfc_get_default_device (nfc_connstring *connstring) +{ + char *env_default_connstring = getenv ("LIBNFC_DEFAULT_DEVICE"); + if (NULL == env_default_connstring) { + // LIBNFC_DEFAULT_DEVICE is not set, we fallback on probing for the first available device + nfc_connstring listed_cs[1]; + size_t szDeviceFound = nfc_list_devices (NULL, listed_cs, 1); + if (szDeviceFound) { + strncpy (*connstring, listed_cs[0], sizeof(nfc_connstring)); + } else { + return false; + } + } else { + strncpy (*connstring, env_default_connstring, sizeof(nfc_connstring)); + } + return true; +} + +/** + * @brief Open a NFC device + * @param connstring The device connection string if specific device is wanted, \c NULL otherwise + * @return Returns pointer to a \a nfc_device struct if successfull; otherwise returns \c NULL value. * - * When it has successfully claimed a NFC device, memory is allocated to save the device information. It will return a pointer to a \a nfc_device_t struct. + * If \e connstring is \c NULL, the \a nfc_get_default_device() function is used. + * + * If \e connstring is set, this function will try to claim the right device using information provided by \e connstring. + * + * When it has successfully claimed a NFC device, memory is allocated to save the device information. + * It will return a pointer to a \a nfc_device struct. * This pointer should be supplied by every next functions of libnfc that should perform an action with this device. * - * @note Depending on the desired operation mode, the device needs to be configured - * by using nfc_initiator_init() or nfc_target_init(), optionally followed by manual tuning of the parameters if the default parameters are not suiting your goals. + * @note Depending on the desired operation mode, the device needs to be configured by using nfc_initiator_init() or nfc_target_init(), + * optionally followed by manual tuning of the parameters if the default parameters are not suiting your goals. */ -nfc_device_t * -nfc_connect (nfc_device_desc_t * pndd) +nfc_device * +nfc_open (nfc_context *context, const nfc_connstring connstring) { - nfc_device_t *pnd = NULL; + nfc_device *pnd = NULL; - if (pndd == NULL) { - size_t szDeviceFound; - nfc_device_desc_t ndd[1]; - nfc_list_devices (ndd, 1, &szDeviceFound); - if (szDeviceFound) { - pndd = &ndd[0]; - } - } - - if (pndd == NULL) + nfc_connstring ncs; + if (connstring == NULL) { + if (!nfc_get_default_device (&ncs)) { + log_fini (); return NULL; - - log_init (); + } + } else { + strncpy (ncs, connstring, sizeof (nfc_connstring)); + } + // Search through the device list for an available device - const struct nfc_driver_t *ndr; - const struct nfc_driver_t **pndr = nfc_drivers; + const struct nfc_driver *ndr; + const struct nfc_driver **pndr = nfc_drivers; while ((ndr = *pndr)) { - // Specific device is requested: using device description pndd - if (0 != strcmp (ndr->name, pndd->pcDriver)) { + // Specific device is requested: using device description + if (0 != strncmp (ndr->name, ncs, strlen(ndr->name))) { pndr++; continue; - } else { - pnd = ndr->connect (pndd); } - // Test if the connection was successful - if (pnd != NULL) { - log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "[%s] has been claimed.", pnd->acName); + pnd = ndr->open (ncs); + // Test if the opening was successful + if (pnd == NULL) { + log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Unable to open \"%s\".", ncs); + log_fini (); return pnd; - } else { - log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "No device found using driver: %s", ndr->name); } - pndr++; + + log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "\"%s\" (%s) has been claimed.", pnd->name, pnd->connstring); + log_fini (); + return pnd; } + + // Too bad, no driver can decode connstring + log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "No driver available to handle \"%s\".", ncs); log_fini (); - // Too bad, no reader is ready to be claimed return NULL; } /** - * @brief Disconnect from a NFC device - * @param pnd \a nfc_device_t struct pointer that represent currently used device + * @brief Close from a NFC device + * @param pnd \a nfc_device struct pointer that represent currently used device * - * Initiator's selected tag is disconnected and the device, including allocated \a nfc_device_t struct, is released. + * Initiator's selected tag is closed and the device, including allocated \a nfc_device struct, is released. */ void -nfc_disconnect (nfc_device_t * pnd) +nfc_close (nfc_device *pnd) { if (pnd) { // Go in idle mode nfc_idle (pnd); - // Disconnect, clean up and release the device - pnd->driver->disconnect (pnd); - - log_fini (); + // Close, clean up and release the device + pnd->driver->close (pnd); + } } /** * @brief Probe for discoverable supported devices (ie. only available for some drivers) + * @return Returns the number of devices found. * @param[out] pnddDevices array of \a nfc_device_desc_t previously allocated by the caller. * @param szDevices size of the \a pnddDevices array. - * @param[out] pszDeviceFound number of devices found. + * */ -void -nfc_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound) +size_t +nfc_list_devices (nfc_context *context, nfc_connstring connstrings[] , size_t szDevices) { - size_t szN; - *pszDeviceFound = 0; - const struct nfc_driver_t *ndr; - const struct nfc_driver_t **pndr = nfc_drivers; + size_t szN; + size_t szDeviceFound = 0; + const struct nfc_driver *ndr; + const struct nfc_driver **pndr = nfc_drivers; - log_init (); while ((ndr = *pndr)) { szN = 0; - if (ndr->probe (pnddDevices + (*pszDeviceFound), szDevices - (*pszDeviceFound), &szN)) { - *pszDeviceFound += szN; + if (ndr->probe (connstrings + (szDeviceFound), szDevices - (szDeviceFound), &szN)) { + szDeviceFound += szN; log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%ld device(s) found using %s driver", (unsigned long) szN, ndr->name); - if (*pszDeviceFound == szDevices) + if (szDeviceFound == szDevices) break; } pndr++; } log_fini (); + return szDeviceFound; } /** - * @brief Configure advanced NFC device settings - * @return Returns \c true if action was successfully performed; otherwise returns \c false. - * @param pnd \a nfc_device_t struct pointer that represent currently used device - * @param ndo \a nfc_device_option_t struct that contains option to set to device - * @param bEnable boolean to activate/disactivate the option + * @brief Set a device's integer-property value + * @return Returns 0 on success, otherwise returns libnfc's error code (negative value) + * @param pnd \a nfc_device struct pointer that represent currently used device + * @param property \a nfc_property which will be set + * @param value integer value + * + * Sets integer property. + * + * @see nfc_property enum values + */ +int +nfc_device_set_property_int (nfc_device *pnd, const nfc_property property, const int value) +{ + HAL (device_set_property_int, pnd, property, value); +} + + +/** + * @brief Set a device's boolean-property value + * @return Returns 0 on success, otherwise returns libnfc's error code (negative value) + * @param pnd \a nfc_device struct pointer that represent currently used device + * @param property \a nfc_property which will be set + * @param bEnable boolean to activate/disactivate the property * * Configures parameters and registers that control for example timing, * modulation, frame and error handling. There are different categories for * configuring the \e PN53X chip features (handle, activate, infinite and * accept). */ -bool -nfc_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable) +int +nfc_device_set_property_bool (nfc_device *pnd, const nfc_property property, const bool bEnable) { - HAL (configure, pnd, ndo, bEnable); + HAL (device_set_property_bool, pnd, property, bEnable); } /** * @brief Initialize NFC device as initiator (reader) - * @return Returns \c true if action was successfully performed; otherwise returns \c false. - * @param pnd \a nfc_device_t struct pointer that represent currently used device + * @return Returns 0 on success, otherwise returns libnfc's error code (negative value) + * @param pnd \a nfc_device struct pointer that represent currently used device * * The NFC device is configured to function as RFID reader. * After initialization it can be used to communicate to passive RFID tags and active NFC devices. * The reader will act as initiator to communicate peer 2 peer (NFCIP) to other active NFC devices. - * - Crc is handled by the device (NDO_HANDLE_CRC = true) - * - Parity is handled the device (NDO_HANDLE_PARITY = true) - * - Cryto1 cipher is disabled (NDO_ACTIVATE_CRYPTO1 = false) - * - Easy framing is enabled (NDO_EASY_FRAMING = true) - * - Auto-switching in ISO14443-4 mode is enabled (NDO_AUTO_ISO14443_4 = true) - * - Invalid frames are not accepted (NDO_ACCEPT_INVALID_FRAMES = false) - * - Multiple frames are not accepted (NDO_ACCEPT_MULTIPLE_FRAMES = false) - * - 14443-A mode is activated (NDO_FORCE_ISO14443_A = true) - * - speed is set to 106 kbps (NDO_FORCE_SPEED_106 = true) - * - Let the device try forever to find a target (NDO_INFINITE_SELECT = true) + * - Crc is handled by the device (NP_HANDLE_CRC = true) + * - Parity is handled the device (NP_HANDLE_PARITY = true) + * - Cryto1 cipher is disabled (NP_ACTIVATE_CRYPTO1 = false) + * - Easy framing is enabled (NP_EASY_FRAMING = true) + * - Auto-switching in ISO14443-4 mode is enabled (NP_AUTO_ISO14443_4 = true) + * - Invalid frames are not accepted (NP_ACCEPT_INVALID_FRAMES = false) + * - Multiple frames are not accepted (NP_ACCEPT_MULTIPLE_FRAMES = false) + * - 14443-A mode is activated (NP_FORCE_ISO14443_A = true) + * - speed is set to 106 kbps (NP_FORCE_SPEED_106 = true) + * - Let the device try forever to find a target (NP_INFINITE_SELECT = true) * - RF field is shortly dropped (if it was enabled) then activated again */ -bool -nfc_initiator_init (nfc_device_t * pnd) +int +nfc_initiator_init (nfc_device *pnd) { + int res = 0; // Drop the field for a while - if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_ACTIVATE_FIELD, false)) < 0) + return res; // Enable field so more power consuming cards can power themselves up - if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_ACTIVATE_FIELD, true)) < 0) + return res; // Let the device try forever to find a target/tag - if (!nfc_configure (pnd, NDO_INFINITE_SELECT, true)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_INFINITE_SELECT, true)) < 0) + return res; // Activate auto ISO14443-4 switching by default - if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, true)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_AUTO_ISO14443_4, true)) < 0) + return res; // Force 14443-A mode - if (!nfc_configure (pnd, NDO_FORCE_ISO14443_A, true)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_FORCE_ISO14443_A, true)) < 0) + return res; // Force speed at 106kbps - if (!nfc_configure (pnd, NDO_FORCE_SPEED_106, true)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_FORCE_SPEED_106, true)) < 0) + return res; // Disallow invalid frame - if (!nfc_configure (pnd, NDO_ACCEPT_INVALID_FRAMES, false)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_ACCEPT_INVALID_FRAMES, false)) < 0) + return res; // Disallow multiple frames - if (!nfc_configure (pnd, NDO_ACCEPT_MULTIPLE_FRAMES, false)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_ACCEPT_MULTIPLE_FRAMES, false)) < 0) + return res; // Make sure we reset the CRC and parity to chip handling. - if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) - return false; - if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_HANDLE_CRC, true)) < 0) + return res; + if ((res = nfc_device_set_property_bool (pnd, NP_HANDLE_PARITY, true)) < 0) + return res; // Activate "easy framing" feature by default - if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, true)) < 0) + return res; // Deactivate the CRYPTO1 cipher, it may could cause problems when still active - if (!nfc_configure (pnd, NDO_ACTIVATE_CRYPTO1, false)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_ACTIVATE_CRYPTO1, false)) < 0) + return res; HAL (initiator_init, pnd); } /** * @brief Select a passive or emulated tag - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns selected passive target count on success, otherwise returns libnfc's error code (negative value) * - * @param pnd \a nfc_device_t struct pointer that represent currently used device + * @param pnd \a nfc_device struct pointer that represent currently used device * @param nm desired modulation * @param pbtInitData optional initiator data used for Felica, ISO14443B, Topaz polling or to select a specific UID in ISO14443A. * @param szInitData length of initiator data \a pbtInitData. @@ -264,20 +338,20 @@ nfc_initiator_init (nfc_device_t * pnd) * - for an ISO/IEC 14443 type B modulation, pbbInitData contains Application Family Identifier (AFI) (see ISO/IEC 14443-3); * - for a FeliCa modulation, pbbInitData contains polling payload (see ISO/IEC 18092 11.2.2.5). * - * @param[out] pnt \a nfc_target_t struct pointer which will filled if available + * @param[out] pnt \a nfc_target struct pointer which will filled if available * * The NFC device will try to find one available passive tag or emulated tag. * * The chip needs to know with what kind of tag it is dealing with, therefore * the initial modulation and speed (106, 212 or 424 kbps) should be supplied. */ -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) +int +nfc_initiator_select_passive_target (nfc_device *pnd, + const nfc_modulation nm, + const uint8_t *pbtInitData, const size_t szInitData, + nfc_target *pnt) { - byte_t abtInit[MAX(12, szInitData)]; + uint8_t abtInit[MAX(12, szInitData)]; size_t szInit; switch (nm.nmt) { @@ -296,13 +370,12 @@ nfc_initiator_select_passive_target (nfc_device_t * pnd, /** * @brief List passive or emulated tags - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns the number of targets found on success, otherwise returns libnfc's error code (negative value) * - * @param pnd \a nfc_device_t struct pointer that represent currently used device + * @param pnd \a nfc_device struct pointer that represent currently used device * @param nm desired modulation - * @param[out] ant array of \a nfc_target_t that will be filled with targets info + * @param[out] ant array of \a nfc_target that will be filled with targets info * @param szTargets size of \a ant (will be the max targets listed) - * @param[out] pszTargetFound pointer where target found counter will be stored * * The NFC device will try to find the available passive tags. Some NFC devices * are capable to emulate passive tags. The standards (ISO18092 and ECMA-340) @@ -311,26 +384,27 @@ nfc_initiator_select_passive_target (nfc_device_t * pnd, * with, therefore the initial modulation and speed (106, 212 or 424 kbps) * should be supplied. */ -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) +int +nfc_initiator_list_passive_targets (nfc_device *pnd, + const nfc_modulation nm, + nfc_target ant[], const size_t szTargets) { - nfc_target_t nt; + nfc_target nt; size_t szTargetFound = 0; - byte_t *pbtInitData = NULL; + uint8_t *pbtInitData = NULL; size_t szInitDataLen = 0; + int res = 0; - pnd->iLastError = 0; + pnd->last_error = 0; // Let the reader only try once to find a tag - if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) { - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_INFINITE_SELECT, false)) < 0) { + return res; } prepare_initiator_data (nm, &pbtInitData, &szInitDataLen); - while (nfc_initiator_select_passive_target (pnd, nm, pbtInitData, szInitDataLen, &nt)) { + while (nfc_initiator_select_passive_target (pnd, nm, pbtInitData, szInitDataLen, &nt) > 0) { nfc_initiator_deselect_target (pnd); if (szTargets == szTargetFound) { break; @@ -339,14 +413,14 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd, bool seen = false; // Check if we've already seen this tag for (i = 0; i < szTargetFound; i++) { - if (memcmp(&(ant[i]), &nt, sizeof (nfc_target_t)) == 0) { + if (memcmp(&(ant[i]), &nt, sizeof (nfc_target)) == 0) { seen = true; } } if (seen) { break; } - memcpy (&(ant[szTargetFound]), &nt, sizeof (nfc_target_t)); + memcpy (&(ant[szTargetFound]), &nt, sizeof (nfc_target)); szTargetFound++; // deselect has no effect on FeliCa and Jewel cards so we'll stop after one... // ISO/IEC 14443 B' cards are polled at 100% probability so it's not possible to detect correctly two cards at the same time @@ -354,29 +428,27 @@ nfc_initiator_list_passive_targets (nfc_device_t * pnd, break; } } - *pszTargetFound = szTargetFound; - - return true; + return szTargetFound; } /** * @brief Polling for NFC targets - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns polled targets count, otherwise returns libnfc's error code (negative value). * - * @param pnd \a nfc_device_t struct pointer that represent currently used device + * @param pnd \a nfc_device struct pointer that represent currently used device * @param ppttTargetTypes array of desired target types * @param szTargetTypes \e ppttTargetTypes count * @param uiPollNr specifies the number of polling (0x01 – 0xFE: 1 up to 254 polling, 0xFF: Endless polling) * @note one polling is a polling for each desired target type * @param uiPeriod indicates the polling period in units of 150 ms (0x01 – 0x0F: 150ms – 2.25s) * @note e.g. if uiPeriod=10, it will poll each desired target type during 1.5s - * @param[out] pnt pointer on \a nfc_target_t (over)writable struct + * @param[out] pnt pointer on \a nfc_target (over)writable struct */ -bool -nfc_initiator_poll_target (nfc_device_t * pnd, - const nfc_modulation_t * pnmModulations, const size_t szModulations, +int +nfc_initiator_poll_target (nfc_device *pnd, + const nfc_modulation *pnmModulations, const size_t szModulations, const uint8_t uiPollNr, const uint8_t uiPeriod, - nfc_target_t * pnt) + nfc_target *pnt) { HAL (initiator_poll_target, pnd, pnmModulations, szModulations, uiPollNr, uiPeriod, pnt); } @@ -384,31 +456,70 @@ nfc_initiator_poll_target (nfc_device_t * pnd, /** * @brief Select a target and request active or passive mode for D.E.P. (Data Exchange Protocol) - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns selected D.E.P targets count on success, otherwise returns libnfc's error code (negative value). * - * @param pnd \a nfc_device_t struct pointer that represent currently used device + * @param pnd \a nfc_device struct pointer that represent currently used device * @param ndm desired D.E.P. mode (\a NDM_ACTIVE or \a NDM_PASSIVE for active, respectively passive mode) - * @param ndiInitiator pointer \a nfc_dep_info_t struct that contains \e NFCID3 and \e General \e Bytes to set to the initiator device (optionnal, can be \e NULL) - * @param[out] pnt is a \a nfc_target_t struct pointer where target information will be put. + * @param ndiInitiator pointer \a nfc_dep_info struct that contains \e NFCID3 and \e General \e Bytes to set to the initiator device (optionnal, can be \e NULL) + * @param[out] pnt is a \a nfc_target struct pointer where target information will be put. * * The NFC device will try to find an available D.E.P. target. The standards * (ISO18092 and ECMA-340) describe the modulation that can be used for reader * to passive communications. * - * @note \a nfc_dep_info_t will be returned when the target was acquired successfully. + * @note \a nfc_dep_info will be returned when the target was acquired successfully. */ -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) +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) { - HAL (initiator_select_dep_target, pnd, ndm, nbr, pndiInitiator, pnt); + HAL (initiator_select_dep_target, pnd, ndm, nbr, pndiInitiator, pnt, timeout); +} + +/** + * @brief Poll a target and request active or passive mode for D.E.P. (Data Exchange Protocol) + * @return Returns selected D.E.P targets count on success, otherwise returns libnfc's error code (negative value). + * + * @param pnd \a nfc_device struct pointer that represent currently used device + * @param ndm desired D.E.P. mode (\a NDM_ACTIVE or \a NDM_PASSIVE for active, respectively passive mode) + * @param ndiInitiator pointer \a nfc_dep_info struct that contains \e NFCID3 and \e General \e Bytes to set to the initiator device (optionnal, can be \e NULL) + * @param[out] pnt is a \a nfc_target struct pointer where target information will be put. + * + * The NFC device will try to find an available D.E.P. target. The standards + * (ISO18092 and ECMA-340) describe the modulation that can be used for reader + * to passive communications. + * + * @note \a nfc_dep_info will be returned when the target was acquired successfully. + */ +int +nfc_initiator_poll_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) +{ + const int period = 300; + int remaining_time = timeout; + int res; + if ((res = nfc_device_set_property_bool (pnd, NP_INFINITE_SELECT, true)) < 0) + return res; + while (remaining_time > 0) { + if ((res = nfc_initiator_select_dep_target (pnd, ndm, nbr, pndiInitiator, pnt, period)) < 0) { + if (res != NFC_ETIMEOUT) + return res; + } + if (res == 1) + return res; + remaining_time -= period; + } + return 0; } /** * @brief Deselect a selected passive or emulated tag - * @return Returns \c true if action was successfully performed; otherwise returns \c false. - * @param pnd \a nfc_device_t struct pointer that represents currently used device + * @return Returns 0 on success, otherwise returns libnfc's error code (negative value). + * @param pnd \a nfc_device struct pointer that represents currently used device * * After selecting and communicating with a passive tag, this function could be * used to deactivate and release the tag. This is very useful when there are @@ -417,19 +528,19 @@ nfc_initiator_select_dep_target (nfc_device_t * pnd, * tag, test it for the available features and support, deselect it and skip to * the next tag until the correct tag is found. */ -bool -nfc_initiator_deselect_target (nfc_device_t * pnd) +int +nfc_initiator_deselect_target (nfc_device *pnd) { HAL (initiator_deselect_target, pnd); } /** * @brief Send data to target then retrieve data from target - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns received bytes count on success, otherwise returns libnfc's error code * * @param pbtTx contains a byte array of the frame that needs to be transmitted. * @param szTx contains the length in bytes. - * @param timeout timeval struct pointer (NULL means infinite) + * @param timeout in milliseconds * * The NFC device (configured as initiator) will transmit the supplied bytes (\a pbtTx) to the target. * It waits for the response and stores the received bytes in the \a pbtRx byte array. @@ -437,25 +548,25 @@ nfc_initiator_deselect_target (nfc_device_t * pnd) * If timeout is not a null pointer, it specifies the maximum interval to wait for the function to be executed. * If timeout is a null pointer, the function blocks indefinitely (until an error is raised or function is completed). * - * If \a NDO_EASY_FRAMING option is disabled the frames will sent and received in raw mode: \e PN53x will not handle input neither output data. + * If \a NP_EASY_FRAMING option is disabled the frames will sent and received in raw mode: \e PN53x will not handle input neither output data. * * The parity bits are handled by the \e PN53x chip. The CRC can be generated automatically or handled manually. * Using this function, frames can be communicated very fast via the NFC initiator to the tag. * * Tests show that on average this way of communicating is much faster than using the regular driver/middle-ware (often supplied by manufacturers). * - * @warning The configuration option \a NDO_HANDLE_PARITY must be set to \c true (the default value). + * @warning The configuration option \a NP_HANDLE_PARITY must be set to \c true (the default value). */ -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) +int +nfc_initiator_transceive_bytes (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, + size_t *pszRx, int timeout) { HAL (initiator_transceive_bytes, pnd, pbtTx, szTx, pbtRx, pszRx, timeout) } /** * @brief Transceive raw bit-frames to a target - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns received bits count on success, otherwise returns libnfc's error code * * @param pbtTx contains a byte array of the frame that needs to be transmitted. * @param szTxBits contains the length in bits. @@ -478,7 +589,6 @@ nfc_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const * nfc_initiator_transceive_bytes() function. * * @param[out] pbtRx response from the tag - * @param[out] pszRxBits \a pbtRx length in bits * @param[out] pbtRxPar parameter contains a byte array of the corresponding parity bits * * The NFC device (configured as \e initiator) will transmit low-level messages @@ -488,20 +598,20 @@ nfc_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const * require to violate the ISO14443-A standard by sending incorrect parity and * CRC bytes. Using this feature you are able to simulate these frames. */ -bool -nfc_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, - byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar) +int +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) { - HAL (initiator_transceive_bits, pnd, pbtTx, szTxBits, pbtTxPar, pbtRx, pszRxBits, pbtRxPar); + HAL (initiator_transceive_bits, pnd, pbtTx, szTxBits, pbtTxPar, pbtRx, pbtRxPar); } /** * @brief Send data to target then retrieve data from target - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns received bytes count on success, otherwise returns libnfc's error code. * * This function is similar to nfc_initiator_transceive_bytes() with the following differences: * - A precise cycles counter will indicate the number of cycles between emission & reception of frames. - * - It only supports mode with \a NDO_EASY_FRAMING option disabled. + * - It only supports mode with \a NP_EASY_FRAMING option disabled. * - Overall communication with the host is heavier and slower. * * Timer control: @@ -512,23 +622,22 @@ nfc_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const s * - If you need to count more cycles, set *cycles to the maximum you expect but don't forget * you'll loose in precision and it'll take more time before timeout, so don't abuse! * - * @warning The configuration option \a NDO_EASY_FRAMING must be set to \c false. - * @warning The configuration option \a NDO_HANDLE_PARITY must be set to \c true (the default value). + * @warning The configuration option \a NP_EASY_FRAMING must be set to \c false. + * @warning The configuration option \a NP_HANDLE_PARITY must be set to \c true (the default value). */ -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) +int +nfc_initiator_transceive_bytes_timed (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, uint32_t *cycles) { - HAL (initiator_transceive_bytes_timed, pnd, pbtTx, szTx, pbtRx, pszRx, cycles) + HAL (initiator_transceive_bytes_timed, pnd, pbtTx, szTx, pbtRx, cycles) } /** * @brief Transceive raw bit-frames to a target - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns received bits count on success, otherwise returns libnfc's error code * * This function is similar to nfc_initiator_transceive_bits() with the following differences: * - A precise cycles counter will indicate the number of cycles between emission & reception of frames. - * - It only supports mode with \a NDO_EASY_FRAMING option disabled and CRC must be handled manually. + * - It only supports mode with \a NP_EASY_FRAMING option disabled and CRC must be handled manually. * - Overall communication with the host is heavier and slower. * * Timer control: @@ -539,40 +648,41 @@ nfc_initiator_transceive_bytes_timed (nfc_device_t * pnd, const byte_t * pbtTx, * - If you need to count more cycles, set *cycles to the maximum you expect but don't forget * you'll loose in precision and it'll take more time before timeout, so don't abuse! * - * @warning The configuration option \a NDO_EASY_FRAMING must be set to \c false. - * @warning The configuration option \a NDO_HANDLE_CRC must be set to \c false. - * @warning The configuration option \a NDO_HANDLE_PARITY must be set to \c true (the default value). + * @warning The configuration option \a NP_EASY_FRAMING must be set to \c false. + * @warning The configuration option \a NP_HANDLE_CRC must be set to \c false. + * @warning The configuration option \a NP_HANDLE_PARITY must be set to \c true (the default value). */ -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) +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) { - HAL (initiator_transceive_bits_timed, pnd, pbtTx, szTxBits, pbtTxPar, pbtRx, pszRxBits, pbtRxPar, cycles); + HAL (initiator_transceive_bits_timed, pnd, pbtTx, szTxBits, pbtTxPar, pbtRx, pbtRxPar, cycles); } /** * @brief Initialize NFC device as an emulated tag - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns received bytes count on success, otherwise returns libnfc's error code * - * @param pnd \a nfc_device_t struct pointer that represent currently used device + * @param pnd \a nfc_device struct pointer that represent currently used device * @param ntm target mode restriction that you want to emulate (eg. NTM_PASSIVE_ONLY) - * @param pnt pointer to \a nfc_target_t struct that represents the wanted emulated target + * @param pnt pointer to \a nfc_target struct that represents the wanted emulated target * * @note \a pnt can be updated by this function: if you set NBR_UNDEFINED * and/or NDM_UNDEFINED (ie. for DEP mode), these fields will be updated. * * @param[out] pbtRx Rx buffer pointer - * @param[out] pszRx received bytes count + * @param[out] szRx received bytes count + * @param timeout in milliseconds * * This function initializes NFC device in \e target mode in order to emulate a * tag using the specified \a nfc_target_mode_t. - * - Crc is handled by the device (NDO_HANDLE_CRC = true) - * - Parity is handled the device (NDO_HANDLE_PARITY = true) - * - Cryto1 cipher is disabled (NDO_ACTIVATE_CRYPTO1 = false) - * - Auto-switching in ISO14443-4 mode is enabled (NDO_AUTO_ISO14443_4 = true) - * - Easy framing is disabled (NDO_EASY_FRAMING = false) - * - Invalid frames are not accepted (NDO_ACCEPT_INVALID_FRAMES = false) - * - Multiple frames are not accepted (NDO_ACCEPT_MULTIPLE_FRAMES = false) + * - Crc is handled by the device (NP_HANDLE_CRC = true) + * - Parity is handled the device (NP_HANDLE_PARITY = true) + * - Cryto1 cipher is disabled (NP_ACTIVATE_CRYPTO1 = false) + * - Auto-switching in ISO14443-4 mode is enabled (NP_AUTO_ISO14443_4 = true) + * - Easy framing is disabled (NP_EASY_FRAMING = false) + * - Invalid frames are not accepted (NP_ACCEPT_INVALID_FRAMES = false) + * - Multiple frames are not accepted (NP_ACCEPT_MULTIPLE_FRAMES = false) * - RF field is dropped * * @warning Be aware that this function will wait (hang) until a command is @@ -580,77 +690,78 @@ nfc_initiator_transceive_bits_timed (nfc_device_t * pnd, const byte_t * pbtTx, c * example would wake up the emulator. After this is received, the send and * receive functions can be used. */ -bool -nfc_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx) +int +nfc_target_init (nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRx, int timeout) { + int res = 0; // Disallow invalid frame - if (!nfc_configure (pnd, NDO_ACCEPT_INVALID_FRAMES, false)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_ACCEPT_INVALID_FRAMES, false)) < 0) + return res; // Disallow multiple frames - if (!nfc_configure (pnd, NDO_ACCEPT_MULTIPLE_FRAMES, false)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_ACCEPT_MULTIPLE_FRAMES, false)) < 0) + return res; // Make sure we reset the CRC and parity to chip handling. - if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) - return false; - if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_HANDLE_CRC, true)) < 0) + return res; + if ((res = nfc_device_set_property_bool (pnd, NP_HANDLE_PARITY, true)) < 0) + return res; // Activate auto ISO14443-4 switching by default - if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, true)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_AUTO_ISO14443_4, true)) < 0) + return res; // Activate "easy framing" feature by default - if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, true)) < 0) + return res; // Deactivate the CRYPTO1 cipher, it may could cause problems when still active - if (!nfc_configure (pnd, NDO_ACTIVATE_CRYPTO1, false)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_ACTIVATE_CRYPTO1, false)) < 0) + return res; // Drop explicitely the field - if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) - return false; + if ((res = nfc_device_set_property_bool (pnd, NP_ACTIVATE_FIELD, false)) < 0) + return res; - HAL (target_init, pnd, pnt, pbtRx, pszRx); + HAL (target_init, pnd, pnt, pbtRx, szRx, timeout); } /** * @brief Turn NFC device in idle mode - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns 0 on success, otherwise returns libnfc's error code. * - * @param pnd \a nfc_device_t struct pointer that represent currently used device + * @param pnd \a nfc_device struct pointer that represent currently used device * * This function switch the device in idle mode. * In initiator mode, the RF field is turned off and the device is set to low power mode (if avaible); * In target mode, the emulation is stoped (no target available from external initiator) and the device is set to low power mode (if avaible). */ -bool -nfc_idle (nfc_device_t * pnd) +int +nfc_idle (nfc_device *pnd) { HAL (idle, pnd); } /** * @brief Abort current running command - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns 0 on success, otherwise returns libnfc's error code. * - * @param pnd \a nfc_device_t struct pointer that represent currently used device + * @param pnd \a nfc_device struct pointer that represent currently used device * * Some commands (ie. nfc_target_init()) are blocking functions and will return only in particular conditions (ie. external initiator request). * This function attempt to abort the current running command. * * @note The blocking function (ie. nfc_target_init()) will failed with DEABORT error. */ -bool -nfc_abort_command (nfc_device_t * pnd) +int +nfc_abort_command (nfc_device *pnd) { HAL (abort_command, pnd); } /** * @brief Send bytes and APDU frames - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns sent bytes count on success, otherwise returns libnfc's error code * - * @param pnd \a nfc_device_t struct pointer that represent currently used device + * @param pnd \a nfc_device struct pointer that represent currently used device * @param pbtTx pointer to Tx buffer * @param szTx size of Tx buffer - * @param timeout timeval struct pointer (NULL means infinite) + * @param timeout in milliseconds * * This function make the NFC device (configured as \e target) send byte frames * (e.g. APDU responses) to the \e initiator. @@ -658,91 +769,131 @@ nfc_abort_command (nfc_device_t * pnd) * If timeout is not a null pointer, it specifies the maximum interval to wait for the function to be executed. * If timeout is a null pointer, the function blocks indefinitely (until an error is raised or function is completed). */ -bool -nfc_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, struct timeval *timeout) +int +nfc_target_send_bytes (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int timeout) { HAL (target_send_bytes, pnd, pbtTx, szTx, timeout); } /** * @brief Receive bytes and APDU frames - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns received bytes count on success, otherwise returns libnfc's error code * - * @param pnd \a nfc_device_t struct pointer that represent currently used device - * @param[out] pbtRx pointer to Rx buffer - * @param[out] pszRx received byte count - * @param timeout timeval struct pointer (NULL means infinite) + * @param pnd \a nfc_device struct pointer that represent currently used device + * @param pbtRx pointer to Rx buffer + * @param szRx size of Rx buffer + * @param timeout in milliseconds * * This function retrieves bytes frames (e.g. ADPU) sent by the \e initiator to the NFC device (configured as \e target). * - * If timeout is not a null pointer, it specifies the maximum interval to wait for the function to be executed. - * If timeout is a null pointer, the function blocks indefinitely (until an error is raised or function is completed). + * If timeout equals to 0, the function blocks indefinitely (until an error is raised or function is completed) + * If timeout equals to -1, the default timeout will be used */ -bool -nfc_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout) +int +nfc_target_receive_bytes (nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, int timeout) { - HAL (target_receive_bytes, pnd, pbtRx, pszRx, timeout); + HAL (target_receive_bytes, pnd, pbtRx, szRx, timeout); } /** * @brief Send raw bit-frames - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns sent bits count on success, otherwise returns libnfc's error code. * * This function can be used to transmit (raw) bit-frames to the \e initiator * using the specified NFC device (configured as \e target). */ -bool -nfc_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar) +int +nfc_target_send_bits (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar) { HAL (target_send_bits, pnd, pbtTx, szTxBits, pbtTxPar); } /** * @brief Receive bit-frames - * @return Returns \c true if action was successfully performed; otherwise returns \c false. + * @return Returns received bits count on success, otherwise returns libnfc's error code + * + * @param pbtRx + * @param szRx * * This function makes it possible to receive (raw) bit-frames. It returns all * the messages that are stored in the FIFO buffer of the \e PN53x chip. It * does not require to send any frame and thereby could be used to snoop frames * that are transmitted by a nearby \e initiator. @note Check out the - * NDO_ACCEPT_MULTIPLE_FRAMES configuration option to avoid losing transmitted + * NP_ACCEPT_MULTIPLE_FRAMES configuration option to avoid losing transmitted * frames. */ -bool -nfc_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar) +int +nfc_target_receive_bits (nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar) { - HAL (target_receive_bits, pnd, pbtRx, pszRxBits, pbtRxPar); + HAL (target_receive_bits, pnd, pbtRx, szRx, pbtRxPar); } +static struct sErrorMessage { + int iErrorCode; + const char *pcErrorMsg; +} sErrorMessages[] = { + /* Chip-level errors (internal errors, RF errors, etc.) */ + { NFC_SUCCESS, "Success" }, + { NFC_EIO, "Input / Output Error" }, + { NFC_EINVARG, "Invalid argument(s)" }, + { NFC_EDEVNOTSUPP, "Not Supported by Device" }, + { NFC_ENOTSUCHDEV, "No Such Device" }, + { NFC_EOVFLOW, "Buffer Overflow" }, + { NFC_ETIMEOUT, "Timeout" }, + { NFC_EOPABORTED, "Operation Aborted" }, + { NFC_ENOTIMPL, "Not (yet) Implemented" }, + { NFC_ETGRELEASED, "Target Released" }, + { NFC_ERFTRANS, "RF Transmission Error" }, + { NFC_ECHIP, "Device's Internal Chip Error" }, +}; + /** - * @brief Return the PCD error string + * @brief Return the last error string * @return Returns a string */ const char * -nfc_strerror (const nfc_device_t * pnd) -{ - return pnd->driver->strerror (pnd); +nfc_strerror (const nfc_device *pnd) +{ + const char *pcRes = "Unknown error"; + size_t i; + for (i = 0; i < (sizeof (sErrorMessages) / sizeof (struct sErrorMessage)); i++) { + if (sErrorMessages[i].iErrorCode == pnd->last_error) { + pcRes = sErrorMessages[i].pcErrorMsg; + break; + } + } + + return pcRes; } /** - * @brief Renders the PCD error in pcStrErrBuf for a maximum size of szBufLen chars + * @brief Renders the last error in pcStrErrBuf for a maximum size of szBufLen chars * @return Returns 0 upon success */ int -nfc_strerror_r (const nfc_device_t * pnd, char *pcStrErrBuf, size_t szBufLen) +nfc_strerror_r (const nfc_device *pnd, char *pcStrErrBuf, size_t szBufLen) { return (snprintf (pcStrErrBuf, szBufLen, "%s", nfc_strerror (pnd)) < 0) ? -1 : 0; } /** - * @brief Display the PCD error a-la perror + * @brief Display the last error occured on a nfc_device */ void -nfc_perror (const nfc_device_t * pnd, const char *pcString) +nfc_perror (const nfc_device *pnd, const char *pcString) { fprintf (stderr, "%s: %s\n", pcString, nfc_strerror (pnd)); } +/** + * @brief Returns last error occured on a nfc_device + */ +int +nfc_device_get_last_error (const nfc_device *pnd) +{ + return pnd->last_error; +} + /* Special data accessors */ /** @@ -750,9 +901,19 @@ nfc_perror (const nfc_device_t * pnd, const char *pcString) * @return Returns a string with the device name */ const char * -nfc_device_name (nfc_device_t * pnd) +nfc_device_get_name (nfc_device *pnd) { - return pnd->acName; + return pnd->name; +} + +/** + * @brief Returns the device connection string + * @return Returns a string with the device connstring + */ +const char * +nfc_device_get_connstring (nfc_device *pnd) +{ + return pnd->connstring; } /* Misc. functions */ diff --git a/log4crc b/log4crc index 1b94d68..8dbf69d 100644 --- a/log4crc +++ b/log4crc @@ -21,5 +21,5 @@ - + diff --git a/test/Makefile.am b/test/Makefile.am index bc28640..1e34224 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -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 diff --git a/test/test_access_storm.c b/test/test_access_storm.c index 7e8408b..558f34c 100644 --- a/test/test_access_storm.c +++ b/test/test_access_storm.c @@ -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); } diff --git a/test/test_dep.c b/test/test_dep.c deleted file mode 100644 index d7b96b3..0000000 --- a/test/test_dep.c +++ /dev/null @@ -1,178 +0,0 @@ -#include -#include -#include -#include - -#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")); -} diff --git a/test/test_dep_active.c b/test/test_dep_active.c new file mode 100644 index 0000000..9072495 --- /dev/null +++ b/test/test_dep_active.c @@ -0,0 +1,185 @@ +#include +#include +#include +#include + +#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")); + } + +} diff --git a/test/test_dep_passive.c b/test/test_dep_passive.c new file mode 100644 index 0000000..e792f15 --- /dev/null +++ b/test/test_dep_passive.c @@ -0,0 +1,282 @@ +#include +#include +#include +#include + +#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")); +} diff --git a/test/test_device_modes_as_dep.c b/test/test_device_modes_as_dep.c new file mode 100644 index 0000000..e03e233 --- /dev/null +++ b/test/test_device_modes_as_dep.c @@ -0,0 +1,212 @@ +#include +#include +#include +#include + +#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; + } +} diff --git a/test/test_register_access.c b/test/test_register_access.c index a713081..f6abfef 100644 --- a/test/test_register_access.c +++ b/test/test_register_access.c @@ -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); } diff --git a/test/test_register_endianness.c b/test/test_register_endianness.c index 19372a3..09d622c 100644 --- a/test/test_register_endianness.c +++ b/test/test_register_endianness.c @@ -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); } diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index c96d2e7..30ea767 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -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 diff --git a/utils/Makefile.am b/utils/Makefile.am index b4b1c3e..5e8b322 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -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 diff --git a/utils/mifare.c b/utils/mifare.c index ef9d147..d9ea0b0 100644 --- a/utils/mifare.c +++ b/utils/mifare.c @@ -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) { diff --git a/utils/mifare.h b/utils/mifare.h index df357df..5260308 100644 --- a/utils/mifare.h +++ b/utils/mifare.h @@ -38,7 +38,7 @@ # include -// 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 { diff --git a/utils/nfc-emulate-forum-tag4.c b/utils/nfc-emulate-forum-tag4.c index b942b96..68edf4a 100644 --- a/utils/nfc-emulate-forum-tag4.c +++ b/utils/nfc-emulate-forum-tag4.c @@ -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); } diff --git a/utils/nfc-list.1 b/utils/nfc-list.1 index 22bfa2e..cbe74ae 100644 --- a/utils/nfc-list.1 +++ b/utils/nfc-list.1 @@ -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 diff --git a/utils/nfc-list.c b/utils/nfc-list.c index 58207a0..fcc9bc2 100644 --- a/utils/nfc-list.c +++ b/utils/nfc-list.c @@ -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; nacName); + 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); } diff --git a/utils/nfc-mfsetuid.c b/utils/nfc-mfsetuid.c index 4134acc..4bf01b6 100644 --- a/utils/nfc-mfsetuid.c +++ b/utils/nfc-mfsetuid.c @@ -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; } diff --git a/utils/nfc-mfultralight.c b/utils/nfc-mfultralight.c index 4ae8ccf..ba7394c 100644 --- a/utils/nfc-mfultralight.c +++ b/utils/nfc-mfultralight.c @@ -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; } diff --git a/utils/nfc-probe.c b/utils/nfc-probe.c new file mode 100644 index 0000000..9536398 --- /dev/null +++ b/utils/nfc-probe.c @@ -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 +# include +# endif +#endif + +#include +#include +#include +#include +#include + +#include + +#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; +} diff --git a/utils/nfc-read-forum-tag3.c b/utils/nfc-read-forum-tag3.c index 7f1b76c..6d11d4c 100644 --- a/utils/nfc-read-forum-tag3.c +++ b/utils/nfc-read-forum-tag3.c @@ -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; bacName); + 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); } diff --git a/utils/nfc-relay-picc.c b/utils/nfc-relay-picc.c index 614e787..74a9fb1 100644 --- a/utils/nfc-relay-picc.c +++ b/utils/nfc-relay-picc.c @@ -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); } diff --git a/utils/nfc-utils.c b/utils/nfc-utils.c index a3416e4..2c9ace7 100644 --- a/utils/nfc-utils.c +++ b/utils/nfc-utils.c @@ -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; } diff --git a/utils/nfc-utils.h b/utils/nfc-utils.h index 3f08177..4243ffc 100644 --- a/utils/nfc-utils.h +++ b/utils/nfc-utils.h @@ -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