Merge branch 'master' into pn532_spi

* master: (43 commits)
  Windows: workaround as libusb is not automatically detected by CMake
  Add usbbus to Makefile.am EXTRA_DIST
  make style
  Add log_posix to Makefile.am
  Split logging internals so that platforms may choose additional or alternate spew mechanisms
  More explicitely ignoring return value as suggested by Ludovic
  Windows: Clean up all compiler warnings and link warnings
  API change
  make style
  pn53x-sam: fix print_nfc_target
  Convert by value passing of nfc_target to pointer for str_nfc_target and nfc_initiator_target_is_present
  Windows: Fix bug when compiling without libusb: skip usbbus.c
  Windows: Fix compilation due to new usbbus file
  Fix bug when compiling without libusb: skip usbbus.c
  Fix scan-build warning: cast increases required alignment from 1 to 4
  Fix cppcheck warning "Obsolete function 'usleep' called"
  Avoid warning about ignoring return value of 'read'
  Fix cppcheck warning "Non reentrant function 'readdir' called"
  conf.h: make it more standard
  uart_posix.c: remove redundant include
  ...
This commit is contained in:
Philippe Teuwen 2013-03-08 23:00:44 +01:00
commit 05b9cde966
53 changed files with 1168 additions and 708 deletions

View file

@ -79,9 +79,9 @@ ADD_DEFINITIONS(-Du_int8_t=uint8_t -Du_int16_t=uint16_t)
IF(MINGW) IF(MINGW)
# force MinGW-w64 in 32bit mode # force MinGW-w64 in 32bit mode
SET(CMAKE_C_FLAGS "-m32 ${CMAKE_C_FLAGS}") SET(CMAKE_C_FLAGS "-m32 ${CMAKE_C_FLAGS}")
SET(CMAKE_MODULE_LINKER_FLAGS "-m32 --enable-stdcall-fixup ${CMAKE_SHARED_LINKER_FLAGS}") SET(CMAKE_MODULE_LINKER_FLAGS "-m32 -Wl,--enable-stdcall-fixup ${CMAKE_SHARED_LINKER_FLAGS}")
SET(CMAKE_SHARED_LINKER_FLAGS "-m32 --enable-stdcall-fixup ${CMAKE_SHARED_LINKER_FLAGS}") SET(CMAKE_SHARED_LINKER_FLAGS "-m32 -Wl,--enable-stdcall-fixup ${CMAKE_SHARED_LINKER_FLAGS}")
SET(CMAKE_EXE_LINKER_FLAGS "-m32 --enable-stdcall-fixup ${CMAKE_EXE_LINKER_FLAGS}") SET(CMAKE_EXE_LINKER_FLAGS "-m32 -Wl,--enable-stdcall-fixup ${CMAKE_EXE_LINKER_FLAGS}")
SET(CMAKE_RC_FLAGS "--target=pe-i386 --output-format=coff ${CMAKE_RC_FLAGS}") SET(CMAKE_RC_FLAGS "--target=pe-i386 --output-format=coff ${CMAKE_RC_FLAGS}")
ENDIF(MINGW) ENDIF(MINGW)
@ -119,6 +119,7 @@ ENDIF(PCSC_INCLUDE_DIRS)
IF(LIBUSB_INCLUDE_DIRS) IF(LIBUSB_INCLUDE_DIRS)
INCLUDE_DIRECTORIES(${LIBUSB_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${LIBUSB_INCLUDE_DIRS})
LINK_DIRECTORIES(${LIBUSB_LIBRARY_DIRS}) LINK_DIRECTORIES(${LIBUSB_LIBRARY_DIRS})
SET(LIBUSB_FOUND TRUE)
ENDIF(LIBUSB_INCLUDE_DIRS) ENDIF(LIBUSB_INCLUDE_DIRS)
# version.rc for Windows # version.rc for Windows

42
HACKING
View file

@ -23,21 +23,35 @@ Here are some directions to get you started:
2.1 When using autotools 2.1 When using autotools
$ autoreconf -Wall -vis $ autoreconf -Wall -vis
2.2 When compiling 2.2 When compiling
$ export CFLAGS="-Wall -g -O2 -Wextra -pipe -funsigned-char -fstrict-aliasing \ 2.2.1 Using extra flags:
-Wchar-subscripts -Wundef -Wshadow -Wcast-align -Wwrite-strings -Wunused \ $ export CFLAGS="-Wall -g -O2 -Wextra -pipe -funsigned-char -fstrict-aliasing \
-Wuninitialized -Wpointer-arith -Wredundant-decls -Winline -Wformat \ -Wchar-subscripts -Wundef -Wshadow -Wcast-align -Wwrite-strings -Wunused \
-Wformat-security -Wswitch-enum -Winit-self -Wmissing-include-dirs \ -Wuninitialized -Wpointer-arith -Wredundant-decls -Winline -Wformat \
-Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition \ -Wformat-security -Wswitch-enum -Winit-self -Wmissing-include-dirs \
-Wbad-function-cast -Wnested-externs -Wmissing-declarations" -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition \
$ ./configure -Wbad-function-cast -Wnested-externs -Wmissing-declarations"
$ make clean $ ./configure
$ make $ make clean
You can chase even more issues by using clang: $ make
$ scan-build ./configure 2.2.2 Using clang:
$ make clean $ scan-build ./configure
$ scan-build make $ make clean
$ scan-build make
2.2.3 Using cppcheck (v1.58 or higher):
$ cppcheck --quiet \
-I include -I libnfc -I libnfc/buses -I libnfc/chips -I libnfc/drivers \
--check-config .
$ cppcheck --quiet --enable=all --std=posix --std=c99 \
-I include -I libnfc -I libnfc/buses -I libnfc/chips -I libnfc/drivers \
-DLOG -D__linux__ \
-DDRIVER_PN53X_USB_ENABLED -DDRIVER_ACR122_PCSC_ENABLED \
-DDRIVER_ACR122_USB_ENABLED -DDRIVER_ACR122S_ENABLED \
-DDRIVER_PN532_UART_ENABLED -DDRIVER_ARYGON_ENABLED \
--force --inconclusive .
2.3 When Debianizing 2.3 When Debianizing
$ lintian *deb $ lintian --info --display-info --display-experimental *deb
or (shorter version)
$ lintian -iIE *deb
3. Preserve cross-platform compatility 3. Preserve cross-platform compatility
The source code should remain compilable across various platforms, The source code should remain compilable across various platforms,

8
NEWS
View file

@ -1,3 +1,11 @@
New in 1.7.0-***:
API Changes:
* Functions
- nfc_initiator_target_is_present() & str_nfc_target()
now take a pointer to nfc_target as argument
New in 1.7.0-rc5: New in 1.7.0-rc5:
API Changes: API Changes:

View file

@ -30,7 +30,7 @@ libnfc.so.4 libnfc4 #MINVER#
nfc_initiator_poll_target@Base 1.7.0~rc2 nfc_initiator_poll_target@Base 1.7.0~rc2
nfc_initiator_select_dep_target@Base 1.7.0~rc2 nfc_initiator_select_dep_target@Base 1.7.0~rc2
nfc_initiator_select_passive_target@Base 1.7.0~rc2 nfc_initiator_select_passive_target@Base 1.7.0~rc2
nfc_initiator_target_is_present@Base 1.7.0~rc2 nfc_initiator_target_is_present@Base 1.7.0~rc6-0
nfc_initiator_transceive_bits@Base 1.7.0~rc2 nfc_initiator_transceive_bits@Base 1.7.0~rc2
nfc_initiator_transceive_bits_timed@Base 1.7.0~rc2 nfc_initiator_transceive_bits_timed@Base 1.7.0~rc2
nfc_initiator_transceive_bytes@Base 1.7.0~rc2 nfc_initiator_transceive_bytes@Base 1.7.0~rc2
@ -53,4 +53,4 @@ libnfc.so.4 libnfc4 #MINVER#
pn53x_write_register@Base 1.7.0~rc2 pn53x_write_register@Base 1.7.0~rc2
str_nfc_baud_rate@Base 1.7.0~rc2 str_nfc_baud_rate@Base 1.7.0~rc2
str_nfc_modulation_type@Base 1.7.0~rc2 str_nfc_modulation_type@Base 1.7.0~rc2
str_nfc_target@Base 1.7.0~rc2 str_nfc_target@Base 1.7.0~rc6-0

View file

@ -36,6 +36,10 @@ main(int argc, const char *argv[])
// Initialize libnfc and set the nfc_context // Initialize libnfc and set the nfc_context
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
warnx("Unable to init libnfc (malloc)\n");
exit(EXIT_FAILURE);
}
// Display libnfc version // Display libnfc version
const char *acLibnfcVersion = nfc_version(); const char *acLibnfcVersion = nfc_version();
@ -50,7 +54,7 @@ main(int argc, const char *argv[])
if (pnd == NULL) { if (pnd == NULL) {
warnx("ERROR: %s", "Unable to open NFC device."); warnx("ERROR: %s", "Unable to open NFC device.");
return EXIT_FAILURE; exit(EXIT_FAILURE);
} }
// Set opened NFC device to initiator mode // Set opened NFC device to initiator mode
if (nfc_initiator_init(pnd) < 0) { if (nfc_initiator_init(pnd) < 0) {
@ -82,5 +86,5 @@ main(int argc, const char *argv[])
nfc_close(pnd); nfc_close(pnd);
// Release the context // Release the context
nfc_exit(context); nfc_exit(context);
return EXIT_SUCCESS; exit(EXIT_SUCCESS);
} }

View file

@ -28,6 +28,10 @@ main(int argc, const char *argv[])
// Initialize libnfc and set the nfc_context // Initialize libnfc and set the nfc_context
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
// Display libnfc version // Display libnfc version
const char *acLibnfcVersion = nfc_version(); const char *acLibnfcVersion = nfc_version();
@ -42,7 +46,7 @@ main(int argc, const char *argv[])
if (pnd == NULL) { if (pnd == NULL) {
ERR("%s", "Unable to open NFC device."); ERR("%s", "Unable to open NFC device.");
return EXIT_FAILURE; exit(EXIT_FAILURE);
} }
// Set opened NFC device to initiator mode // Set opened NFC device to initiator mode
if (nfc_initiator_init(pnd) < 0) { if (nfc_initiator_init(pnd) < 0) {
@ -74,5 +78,5 @@ main(int argc, const char *argv[])
nfc_close(pnd); nfc_close(pnd);
// Release the context // Release the context
nfc_exit(context); nfc_exit(context);
return EXIT_SUCCESS; exit(EXIT_SUCCESS);
} }

View file

@ -151,34 +151,47 @@ main(int argc, char *argv[])
nfc_context *context; nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
// Try to open the NFC reader // Try to open the NFC reader
pnd = nfc_open(context, NULL); pnd = nfc_open(context, NULL);
if (!pnd) { if (pnd == NULL) {
printf("Error opening NFC reader\n"); ERR("Error opening NFC reader");
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Initialise NFC device as "initiator" // Initialise NFC device as "initiator"
if (nfc_initiator_init(pnd) < 0) { if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init"); nfc_perror(pnd, "nfc_initiator_init");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Configure the CRC // Configure the CRC
if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) { if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror(pnd, "nfc_device_set_property_bool");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Use raw send/receive methods // Use raw send/receive methods
if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) { if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror(pnd, "nfc_device_set_property_bool");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Disable 14443-4 autoswitching // Disable 14443-4 autoswitching
if (nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, false) < 0) { if (nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, false) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror(pnd, "nfc_device_set_property_bool");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -189,7 +202,7 @@ main(int argc, char *argv[])
printf("Error: No tag available\n"); printf("Error: No tag available\n");
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
return EXIT_FAILURE; exit(EXIT_FAILURE);
} }
memcpy(abtAtqa, abtRx, 2); memcpy(abtAtqa, abtRx, 2);
@ -319,5 +332,5 @@ main(int argc, char *argv[])
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
return EXIT_SUCCESS; exit(EXIT_SUCCESS);
} }

View file

@ -49,14 +49,17 @@
#define MAX_FRAME_LEN 264 #define MAX_FRAME_LEN 264
static nfc_device *pnd; static nfc_device *pnd;
static nfc_context *context;
static void stop_dep_communication(int sig) static void stop_dep_communication(int sig)
{ {
(void) sig; (void) sig;
if (pnd) if (pnd != NULL) {
nfc_abort_command(pnd); nfc_abort_command(pnd);
else } else {
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
} }
int int
@ -68,16 +71,20 @@ main(int argc, const char *argv[])
if (argc > 1) { if (argc > 1) {
printf("Usage: %s\n", argv[0]); printf("Usage: %s\n", argv[0]);
return EXIT_FAILURE; exit(EXIT_FAILURE);
} }
nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
pnd = nfc_open(context, NULL); pnd = nfc_open(context, NULL);
if (!pnd) { if (pnd == NULL) {
printf("Unable to open NFC device.\n"); ERR("Unable to open NFC device.");
return EXIT_FAILURE; nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("NFC device: %s\n opened", nfc_device_get_name(pnd)); printf("NFC device: %s\n opened", nfc_device_get_name(pnd));
@ -85,20 +92,26 @@ main(int argc, const char *argv[])
if (nfc_initiator_init(pnd) < 0) { if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init"); nfc_perror(pnd, "nfc_initiator_init");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
if (nfc_initiator_select_dep_target(pnd, NDM_PASSIVE, NBR_212, NULL, &nt, 1000) < 0) { if (nfc_initiator_select_dep_target(pnd, NDM_PASSIVE, NBR_212, NULL, &nt, 1000) < 0) {
nfc_perror(pnd, "nfc_initiator_select_dep_target"); nfc_perror(pnd, "nfc_initiator_select_dep_target");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
print_nfc_target(nt, false); print_nfc_target(&nt, false);
printf("Sending: %s\n", abtTx); printf("Sending: %s\n", abtTx);
int res; int res;
if ((res = nfc_initiator_transceive_bytes(pnd, abtTx, sizeof(abtTx), abtRx, sizeof(abtRx), 0)) < 0) { if ((res = nfc_initiator_transceive_bytes(pnd, abtTx, sizeof(abtTx), abtRx, sizeof(abtRx), 0)) < 0) {
nfc_perror(pnd, "nfc_initiator_transceive_bytes"); nfc_perror(pnd, "nfc_initiator_transceive_bytes");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
abtRx[res] = 0; abtRx[res] = 0;
@ -106,11 +119,12 @@ main(int argc, const char *argv[])
if (nfc_initiator_deselect_target(pnd) < 0) { if (nfc_initiator_deselect_target(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_deselect_target"); nfc_perror(pnd, "nfc_initiator_deselect_target");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
error:
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
return EXIT_SUCCESS; exit(EXIT_SUCCESS);
} }

View file

@ -48,14 +48,17 @@
#define MAX_FRAME_LEN 264 #define MAX_FRAME_LEN 264
static nfc_device *pnd; static nfc_device *pnd;
static nfc_context *context;
static void stop_dep_communication(int sig) static void stop_dep_communication(int sig)
{ {
(void) sig; (void) sig;
if (pnd) if (pnd != NULL) {
nfc_abort_command(pnd); nfc_abort_command(pnd);
else } else {
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
} }
int int
@ -65,8 +68,16 @@ main(int argc, const char *argv[])
int szRx; int szRx;
uint8_t abtTx[] = "Hello Mars!"; uint8_t abtTx[] = "Hello Mars!";
nfc_context *context; if (argc > 1) {
printf("Usage: %s\n", argv[0]);
exit(EXIT_FAILURE);
}
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
#define MAX_DEVICE_COUNT 2 #define MAX_DEVICE_COUNT 2
nfc_connstring connstrings[MAX_DEVICE_COUNT]; nfc_connstring connstrings[MAX_DEVICE_COUNT];
size_t szDeviceFound = nfc_list_devices(context, connstrings, MAX_DEVICE_COUNT); size_t szDeviceFound = nfc_list_devices(context, connstrings, MAX_DEVICE_COUNT);
@ -80,12 +91,8 @@ main(int argc, const char *argv[])
pnd = nfc_open(context, connstrings[1]); pnd = nfc_open(context, connstrings[1]);
} else { } else {
printf("No device found.\n"); printf("No device found.\n");
return EXIT_FAILURE; nfc_exit(context);
} exit(EXIT_FAILURE);
if (argc > 1) {
printf("Usage: %s\n", argv[0]);
return EXIT_FAILURE;
} }
nfc_target nt = { nfc_target nt = {
@ -109,27 +116,32 @@ main(int argc, const char *argv[])
}, },
}; };
if (!pnd) { if (pnd == NULL) {
printf("Unable to open NFC device.\n"); printf("Unable to open NFC device.\n");
return EXIT_FAILURE; nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("NFC device: %s opened\n", nfc_device_get_name(pnd)); printf("NFC device: %s opened\n", nfc_device_get_name(pnd));
signal(SIGINT, stop_dep_communication); signal(SIGINT, stop_dep_communication);
printf("NFC device will now act as: "); printf("NFC device will now act as: ");
print_nfc_target(nt, false); print_nfc_target(&nt, false);
printf("Waiting for initiator request...\n"); printf("Waiting for initiator request...\n");
if ((szRx = nfc_target_init(pnd, &nt, abtRx, sizeof(abtRx), 0)) < 0) { if ((szRx = nfc_target_init(pnd, &nt, abtRx, sizeof(abtRx), 0)) < 0) {
nfc_perror(pnd, "nfc_target_init"); nfc_perror(pnd, "nfc_target_init");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("Initiator request received. Waiting for data...\n"); printf("Initiator request received. Waiting for data...\n");
if ((szRx = nfc_target_receive_bytes(pnd, abtRx, sizeof(abtRx), 0)) < 0) { if ((szRx = nfc_target_receive_bytes(pnd, abtRx, sizeof(abtRx), 0)) < 0) {
nfc_perror(pnd, "nfc_target_receive_bytes"); nfc_perror(pnd, "nfc_target_receive_bytes");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
abtRx[(size_t) szRx] = '\0'; abtRx[(size_t) szRx] = '\0';
printf("Received: %s\n", abtRx); printf("Received: %s\n", abtRx);
@ -137,12 +149,13 @@ main(int argc, const char *argv[])
printf("Sending: %s\n", abtTx); printf("Sending: %s\n", abtTx);
if (nfc_target_send_bytes(pnd, abtTx, sizeof(abtTx), 0) < 0) { if (nfc_target_send_bytes(pnd, abtTx, sizeof(abtTx), 0) < 0) {
nfc_perror(pnd, "nfc_target_send_bytes"); nfc_perror(pnd, "nfc_target_send_bytes");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("Data sent.\n"); printf("Data sent.\n");
error:
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
return EXIT_SUCCESS; exit(EXIT_SUCCESS);
} }

View file

@ -74,14 +74,16 @@
#include "utils/nfc-utils.h" #include "utils/nfc-utils.h"
static nfc_device *pnd; static nfc_device *pnd;
static nfc_context *context;
static void static void
stop_emulation(int sig) stop_emulation(int sig)
{ {
(void)sig; (void)sig;
if (pnd) { if (pnd != NULL) {
nfc_abort_command(pnd); nfc_abort_command(pnd);
} else { } else {
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
@ -185,12 +187,16 @@ main(int argc, char *argv[])
signal(SIGINT, stop_emulation); signal(SIGINT, stop_emulation);
nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
pnd = nfc_open(context, NULL); pnd = nfc_open(context, NULL);
if (pnd == NULL) { if (pnd == NULL) {
ERR("Unable to open NFC device"); ERR("Unable to open NFC device");
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -198,18 +204,13 @@ main(int argc, char *argv[])
printf("Emulating NDEF tag now, please touch it with a second NFC device\n"); printf("Emulating NDEF tag now, please touch it with a second NFC device\n");
if (nfc_emulate_target(pnd, &emulator, 0) < 0) { if (nfc_emulate_target(pnd, &emulator, 0) < 0) {
goto error; nfc_perror(pnd, argv[0]);
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
error:
if (pnd) {
nfc_perror(pnd, argv[0]);
nfc_close(pnd);
nfc_exit(context);
}
} }

View file

@ -67,8 +67,9 @@ intr_hdlr(int sig)
(void) sig; (void) sig;
printf("\nQuitting...\n"); printf("\nQuitting...\n");
if (pnd != NULL) { if (pnd != NULL) {
nfc_close(pnd); nfc_abort_command(pnd);
} }
nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -183,16 +184,21 @@ main(int argc, char *argv[])
#endif #endif
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
// Try to open the NFC reader ERR("Unable to init libnfc (malloc)");
pnd = nfc_open(context, NULL); exit(EXIT_FAILURE);
}
// Display libnfc version // Display libnfc version
acLibnfcVersion = nfc_version(); acLibnfcVersion = nfc_version();
printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion); printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
// Try to open the NFC reader
pnd = nfc_open(context, NULL);
if (pnd == NULL) { if (pnd == NULL) {
ERR("Unable to open NFC device"); ERR("Unable to open NFC device");
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -260,13 +266,15 @@ main(int argc, char *argv[])
*/ */
printf("%s will emulate this ISO14443-A tag:\n", argv[0]); printf("%s will emulate this ISO14443-A tag:\n", argv[0]);
print_nfc_target(nt, true); print_nfc_target(&nt, true);
// Switch off NP_EASY_FRAMING if target is not ISO14443-4 // 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)); nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, (nt.nti.nai.btSak & SAK_ISO14443_4_COMPLIANT));
printf("NFC device (configured as target) is now emulating the tag, please touch it with a second NFC device (initiator)\n"); printf("NFC device (configured as target) is now emulating the tag, please touch it with a second NFC device (initiator)\n");
if (!nfc_target_emulate_tag(pnd, &nt)) { if (!nfc_target_emulate_tag(pnd, &nt)) {
nfc_perror(pnd, "nfc_target_emulate_tag"); nfc_perror(pnd, "nfc_target_emulate_tag");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View file

@ -59,6 +59,7 @@
static uint8_t abtRecv[MAX_FRAME_LEN]; static uint8_t abtRecv[MAX_FRAME_LEN];
static int szRecvBits; static int szRecvBits;
static nfc_device *pnd; static nfc_device *pnd;
static nfc_context *context;
// ISO14443A Anti-Collision response // ISO14443A Anti-Collision response
uint8_t abtAtqa[2] = { 0x04, 0x00 }; uint8_t abtAtqa[2] = { 0x04, 0x00 };
@ -126,14 +127,18 @@ main(int argc, char *argv[])
signal(SIGINT, intr_hdlr); signal(SIGINT, intr_hdlr);
#endif #endif
nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
// Try to open the NFC device // Try to open the NFC device
pnd = nfc_open(context, NULL); pnd = nfc_open(context, NULL);
if (pnd == NULL) { if (pnd == NULL) {
printf("Unable to open NFC device\n"); ERR("Unable to open NFC device");
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -162,13 +167,17 @@ main(int argc, char *argv[])
if ((szRecvBits = nfc_target_init(pnd, &nt, abtRecv, sizeof(abtRecv), 0)) < 0) { if ((szRecvBits = nfc_target_init(pnd, &nt, abtRecv, sizeof(abtRecv), 0)) < 0) {
nfc_perror(pnd, "nfc_target_init"); nfc_perror(pnd, "nfc_target_init");
ERR("Could not come out of auto-emulation, no command was received"); ERR("Could not come out of auto-emulation, no command was received");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("[+] Received initiator command: "); printf("[+] Received initiator command: ");
print_hex_bits(abtRecv, (size_t) szRecvBits); print_hex_bits(abtRecv, (size_t) szRecvBits);
printf("[+] Configuring communication\n"); printf("[+] Configuring communication\n");
if ((nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) || (nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, true) < 0)) { if ((nfc_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"); nfc_perror(pnd, "nfc_device_set_property_bool");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
printf("[+] Done, the emulated tag is initialized with UID: %02X%02X%02X%02X\n\n", abtUidBcc[0], abtUidBcc[1], printf("[+] Done, the emulated tag is initialized with UID: %02X%02X%02X%02X\n\n", abtUidBcc[0], abtUidBcc[1],
@ -211,7 +220,9 @@ main(int argc, char *argv[])
// Send and print the command to the screen // Send and print the command to the screen
if (nfc_target_send_bits(pnd, pbtTx, szTxBits, NULL) < 0) { if (nfc_target_send_bits(pnd, pbtTx, szTxBits, NULL) < 0) {
nfc_perror(pnd, "nfc_target_send_bits"); nfc_perror(pnd, "nfc_target_send_bits");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
if (!quiet_output) { if (!quiet_output) {
printf("T: "); printf("T: ");
@ -223,9 +234,4 @@ main(int argc, char *argv[])
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
error:
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }

View file

@ -179,34 +179,47 @@ main(int argc, char *argv[])
nfc_context *context; nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
// Try to open the NFC reader // Try to open the NFC reader
pnd = nfc_open(context, NULL); pnd = nfc_open(context, NULL);
if (!pnd) { if (pnd == NULL) {
printf("Error opening NFC reader\n"); ERR("Error opening NFC reader");
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Initialise NFC device as "initiator" // Initialise NFC device as "initiator"
if (nfc_initiator_init(pnd) < 0) { if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init"); nfc_perror(pnd, "nfc_initiator_init");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Configure the CRC // Configure the CRC
if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) { if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror(pnd, "nfc_device_set_property_bool");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Use raw send/receive methods // Use raw send/receive methods
if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) { if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror(pnd, "nfc_device_set_property_bool");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Disable 14443-4 autoswitching // Disable 14443-4 autoswitching
if (nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, false) < 0) { if (nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, false) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror(pnd, "nfc_device_set_property_bool");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -217,7 +230,7 @@ main(int argc, char *argv[])
printf("Error: No tag available\n"); printf("Error: No tag available\n");
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
return 1; exit(EXIT_FAILURE);
} }
memcpy(abtAtqa, abtRx, 2); memcpy(abtAtqa, abtRx, 2);
@ -353,8 +366,7 @@ main(int argc, char *argv[])
} }
} }
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
return EXIT_SUCCESS; exit(EXIT_SUCCESS);
} }

View file

@ -38,6 +38,7 @@
#endif // HAVE_CONFIG_H #endif // HAVE_CONFIG_H
#include <err.h> #include <err.h>
#include <inttypes.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stddef.h> #include <stddef.h>
@ -52,14 +53,17 @@
#define MAX_DEVICE_COUNT 16 #define MAX_DEVICE_COUNT 16
static nfc_device *pnd = NULL; static nfc_device *pnd = NULL;
static nfc_context *context;
static void stop_polling(int sig) static void stop_polling(int sig)
{ {
(void) sig; (void) sig;
if (pnd) if (pnd != NULL)
nfc_abort_command(pnd); nfc_abort_command(pnd);
else else {
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
} }
static void static void
@ -103,23 +107,29 @@ main(int argc, const char *argv[])
nfc_target nt; nfc_target nt;
int res = 0; int res = 0;
nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
pnd = nfc_open(context, NULL); pnd = nfc_open(context, NULL);
if (pnd == NULL) { if (pnd == NULL) {
ERR("%s", "Unable to open NFC device."); ERR("%s", "Unable to open NFC device.");
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (nfc_initiator_init(pnd) < 0) { if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init"); nfc_perror(pnd, "nfc_initiator_init");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
printf("NFC reader: %s opened\n", nfc_device_get_name(pnd)); 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); printf("NFC device will poll during %ld ms (%u pollings of %lu ms for %" PRIdPTR " 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) { if ((res = nfc_initiator_poll_target(pnd, nmModulations, szModulations, uiPollNr, uiPeriod, &nt)) < 0) {
nfc_perror(pnd, "nfc_initiator_poll_target"); nfc_perror(pnd, "nfc_initiator_poll_target");
nfc_close(pnd); nfc_close(pnd);
@ -128,7 +138,7 @@ main(int argc, const char *argv[])
} }
if (res > 0) { if (res > 0) {
print_nfc_target(nt, verbose); print_nfc_target(&nt, verbose);
} else { } else {
printf("No target found.\n"); printf("No target found.\n");
} }

View file

@ -37,6 +37,7 @@
# include "config.h" # include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
@ -89,13 +90,13 @@ main(int argc, char *argv[])
for (arg = 1; arg < argc; arg++) { for (arg = 1; arg < argc; arg++) {
if (0 == strcmp(argv[arg], "-h")) { if (0 == strcmp(argv[arg], "-h")) {
print_usage(argv); print_usage(argv);
return EXIT_SUCCESS; exit(EXIT_SUCCESS);
} else if (0 == strcmp(argv[arg], "-q")) { } else if (0 == strcmp(argv[arg], "-q")) {
quiet_output = true; quiet_output = true;
} else { } else {
ERR("%s is not supported option.", argv[arg]); ERR("%s is not supported option.", argv[arg]);
print_usage(argv); print_usage(argv);
return EXIT_FAILURE; exit(EXIT_FAILURE);
} }
} }
@ -110,20 +111,26 @@ main(int argc, char *argv[])
nfc_context *context; nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
nfc_connstring connstrings[MAX_DEVICE_COUNT]; nfc_connstring connstrings[MAX_DEVICE_COUNT];
// List available devices // List available devices
size_t szFound = nfc_list_devices(context, connstrings, MAX_DEVICE_COUNT); size_t szFound = nfc_list_devices(context, connstrings, MAX_DEVICE_COUNT);
if (szFound < 2) { if (szFound < 2) {
ERR("%zd device found but two opened devices are needed to relay NFC.", szFound); ERR("%" PRIdPTR " device found but two opened devices are needed to relay NFC.", szFound);
return EXIT_FAILURE; nfc_exit(context);
exit(EXIT_FAILURE);
} }
// Try to open the NFC emulator device // Try to open the NFC emulator device
pndTag = nfc_open(context, connstrings[0]); pndTag = nfc_open(context, connstrings[0]);
if (pndTag == NULL) { if (pndTag == NULL) {
printf("Error opening NFC emulator device\n"); ERR("Error opening NFC emulator device");
return EXIT_FAILURE; nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("Hint: tag <---> initiator (relay) <---> target (relay) <---> original reader\n\n"); printf("Hint: tag <---> initiator (relay) <---> target (relay) <---> original reader\n\n");
@ -153,30 +160,44 @@ main(int argc, char *argv[])
ERR("%s", "Initialization of NFC emulator failed"); ERR("%s", "Initialization of NFC emulator failed");
nfc_close(pndTag); nfc_close(pndTag);
nfc_exit(context); nfc_exit(context);
return EXIT_FAILURE; exit(EXIT_FAILURE);
} }
printf("%s", "Configuring emulator settings..."); printf("%s", "Configuring emulator settings...");
if ((nfc_device_set_property_bool(pndTag, NP_HANDLE_CRC, false) < 0) || 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_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"); nfc_perror(pndTag, "nfc_device_set_property_bool");
nfc_close(pndTag);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
printf("%s", "Done, emulated tag is initialized"); printf("%s", "Done, emulated tag is initialized");
// Try to open the NFC reader // Try to open the NFC reader
pndReader = nfc_open(context, connstrings[1]); pndReader = nfc_open(context, connstrings[1]);
if (pndReader == NULL) {
printf("Error opening NFC reader device\n");
nfc_close(pndTag);
nfc_exit(context);
exit(EXIT_FAILURE);
}
printf("NFC reader device: %s opened", nfc_device_get_name(pndReader)); printf("NFC reader device: %s opened", nfc_device_get_name(pndReader));
printf("%s", "Configuring NFC reader settings..."); printf("%s", "Configuring NFC reader settings...");
if (nfc_initiator_init(pndReader) < 0) { if (nfc_initiator_init(pndReader) < 0) {
nfc_perror(pndReader, "nfc_initiator_init"); nfc_perror(pndReader, "nfc_initiator_init");
nfc_close(pndTag);
nfc_close(pndReader);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if ((nfc_device_set_property_bool(pndReader, NP_HANDLE_CRC, false) < 0) || 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_HANDLE_PARITY, false) < 0) ||
(nfc_device_set_property_bool(pndReader, NP_ACCEPT_INVALID_FRAMES, true)) < 0) { (nfc_device_set_property_bool(pndReader, NP_ACCEPT_INVALID_FRAMES, true)) < 0) {
nfc_perror(pndReader, "nfc_device_set_property_bool"); nfc_perror(pndReader, "nfc_device_set_property_bool");
nfc_close(pndTag);
nfc_close(pndReader);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
printf("%s", "Done, relaying frames now!"); printf("%s", "Done, relaying frames now!");
@ -189,12 +210,18 @@ main(int argc, char *argv[])
// Drop down field for a very short time (original tag will reboot) // Drop down field for a very short time (original tag will reboot)
if (nfc_device_set_property_bool(pndReader, NP_ACTIVATE_FIELD, false) < 0) { if (nfc_device_set_property_bool(pndReader, NP_ACTIVATE_FIELD, false) < 0) {
nfc_perror(pndReader, "nfc_device_set_property_bool"); nfc_perror(pndReader, "nfc_device_set_property_bool");
nfc_close(pndTag);
nfc_close(pndReader);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (!quiet_output) if (!quiet_output)
printf("\n"); printf("\n");
if (nfc_device_set_property_bool(pndReader, NP_ACTIVATE_FIELD, true) < 0) { if (nfc_device_set_property_bool(pndReader, NP_ACTIVATE_FIELD, true) < 0) {
nfc_perror(pndReader, "nfc_device_set_property_bool"); nfc_perror(pndReader, "nfc_device_set_property_bool");
nfc_close(pndTag);
nfc_close(pndReader);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
@ -209,6 +236,9 @@ main(int argc, char *argv[])
// Redirect the answer back to the reader // Redirect the answer back to the reader
if (nfc_target_send_bits(pndTag, abtTagRx, szTagRxBits, abtTagRxPar) < 0) { if (nfc_target_send_bits(pndTag, abtTagRx, szTagRxBits, abtTagRxPar) < 0) {
nfc_perror(pndTag, "nfc_target_send_bits"); nfc_perror(pndTag, "nfc_target_send_bits");
nfc_close(pndTag);
nfc_close(pndReader);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Print the tag frame to the screen // Print the tag frame to the screen

View file

@ -51,7 +51,7 @@ int
main(int argc, const char *argv[]) main(int argc, const char *argv[])
{ {
size_t i; size_t i;
nfc_device *pnd; nfc_device *pnd = NULL;
const char *acLibnfcVersion; const char *acLibnfcVersion;
bool result; bool result;
int res = 0; int res = 0;
@ -63,11 +63,16 @@ main(int argc, const char *argv[])
const uint8_t pncmd_diagnose_ram_test[] = { Diagnose, 0x02 }; const uint8_t pncmd_diagnose_ram_test[] = { Diagnose, 0x02 };
if (argc > 1) { if (argc > 1) {
errx(1, "usage: %s", argv[0]); printf("Usage: %s", argv[0]);
exit(EXIT_FAILURE);
} }
nfc_context *context; nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
// Display libnfc version // Display libnfc version
acLibnfcVersion = nfc_version(); acLibnfcVersion = nfc_version();
@ -85,7 +90,8 @@ main(int argc, const char *argv[])
if (pnd == NULL) { if (pnd == NULL) {
ERR("%s", "Unable to open NFC device."); ERR("%s", "Unable to open NFC device.");
return EXIT_FAILURE; nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("NFC device [%s] opened.\n", nfc_device_get_name(pnd)); printf("NFC device [%s] opened.\n", nfc_device_get_name(pnd));
@ -119,4 +125,7 @@ main(int argc, const char *argv[])
nfc_perror(pnd, "pn53x_transceive: cannot diagnose RAM"); nfc_perror(pnd, "pn53x_transceive: cannot diagnose RAM");
} }
} }
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_SUCCESS);
} }

View file

@ -75,10 +75,12 @@ main(int argc, const char *argv[])
(void) argc; (void) argc;
(void) argv; (void) argv;
int ret = EXIT_FAILURE;
nfc_context *context; nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
// Display libnfc version // Display libnfc version
const char *acLibnfcVersion = nfc_version(); const char *acLibnfcVersion = nfc_version();
@ -90,7 +92,8 @@ main(int argc, const char *argv[])
if (pnd == NULL) { if (pnd == NULL) {
ERR("%s", "Unable to open NFC device."); ERR("%s", "Unable to open NFC device.");
return EXIT_FAILURE; nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("NFC device: %s opened\n", nfc_device_get_name(pnd)); printf("NFC device: %s opened\n", nfc_device_get_name(pnd));
@ -107,7 +110,9 @@ main(int argc, const char *argv[])
printf("\n"); printf("\n");
if ((input < '1') || (input > '3')) { if ((input < '1') || (input > '3')) {
ERR("%s", "Invalid selection."); ERR("%s", "Invalid selection.");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
/* /*
@ -125,7 +130,9 @@ main(int argc, const char *argv[])
// FIXME Its a private pn53x function // FIXME Its a private pn53x function
if (pn532_SAMConfiguration(pnd, mode, 0) < 0) { if (pn532_SAMConfiguration(pnd, mode, 0) < 0) {
nfc_perror(pnd, "pn53x_SAMConfiguration"); nfc_perror(pnd, "pn53x_SAMConfiguration");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("Now the SAM is readable for 1 minute from an external reader.\n"); printf("Now the SAM is readable for 1 minute from an external reader.\n");
wait_one_minute(); wait_one_minute();
@ -136,13 +143,17 @@ main(int argc, const char *argv[])
// Set opened NFC device to initiator mode // Set opened NFC device to initiator mode
if (nfc_initiator_init_secure_element(pnd) < 0) { if (nfc_initiator_init_secure_element(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init_secure_element"); nfc_perror(pnd, "nfc_initiator_init_secure_element");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
// Let the reader only try once to find a tag // Let the reader only try once to find a tag
if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) { if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror(pnd, "nfc_device_set_property_bool");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
// Read the SAM's info // Read the SAM's info
const nfc_modulation nmSAM = { const nfc_modulation nmSAM = {
@ -154,16 +165,22 @@ main(int argc, const char *argv[])
int res; int res;
if ((res = nfc_initiator_select_passive_target(pnd, nmSAM, NULL, 0, &nt)) < 0) { if ((res = nfc_initiator_select_passive_target(pnd, nmSAM, NULL, 0, &nt)) < 0) {
nfc_perror(pnd, "nfc_initiator_select_passive_target"); nfc_perror(pnd, "nfc_initiator_select_passive_target");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} else if (res == 0) { } else if (res == 0) {
ERR("No SAM found."); ERR("No SAM found.");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} else if (res == 1) { } else if (res == 1) {
printf("The following ISO14443A tag (SAM) was found:\n"); printf("The following ISO14443A tag (SAM) was found:\n");
print_nfc_target(nt, true); print_nfc_target(&nt, true);
} else { } else {
ERR("%s", "More than one ISO14442 tag found as SAM."); ERR("%s", "More than one ISO14442 tag found as SAM.");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
} }
break; break;
@ -172,7 +189,9 @@ main(int argc, const char *argv[])
// FIXME Its a private pn53x function // FIXME Its a private pn53x function
if (pn532_SAMConfiguration(pnd, mode, 0) < 0) { if (pn532_SAMConfiguration(pnd, mode, 0) < 0) {
nfc_perror(pnd, "pn53x_SAMConfiguration"); nfc_perror(pnd, "pn53x_SAMConfiguration");
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
uint8_t abtRx[MAX_FRAME_LEN]; uint8_t abtRx[MAX_FRAME_LEN];
@ -195,7 +214,9 @@ main(int argc, const char *argv[])
printf("Please note that NFC device (configured as target) stay in target mode until it receive RATS, ATR_REQ or proprietary command.\n"); printf("Please note that NFC device (configured as target) stay in target mode until it receive RATS, ATR_REQ or proprietary command.\n");
if (nfc_target_init(pnd, &nt, abtRx, sizeof(abtRx), 0) < 0) { if (nfc_target_init(pnd, &nt, abtRx, sizeof(abtRx), 0) < 0) {
nfc_perror(pnd, "nfc_target_init"); nfc_perror(pnd, "nfc_target_init");
return EXIT_FAILURE; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
// wait_one_minute (); // wait_one_minute ();
} }
@ -204,15 +225,12 @@ main(int argc, const char *argv[])
// This should not happend... nothing to do. // This should not happend... nothing to do.
break; break;
} }
ret = EXIT_SUCCESS;
error:
// Disconnect from the SAM // Disconnect from the SAM
pn532_SAMConfiguration(pnd, PSM_NORMAL, -1); pn532_SAMConfiguration(pnd, PSM_NORMAL, -1);
// Close NFC device // Close NFC device
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
exit(EXIT_SUCCESS);
exit(ret);
} }

View file

@ -48,15 +48,16 @@
#include <time.h> #include <time.h>
#ifndef _WIN32 #ifndef _WIN32
// Needed by sleep() under Unix # include <time.h>
# include <unistd.h> # define msleep(x) do { \
# define sleep usleep struct timespec xsleep; \
# define SUSP_TIME 1000 // usecs. xsleep.tv_sec = x / 1000; \
xsleep.tv_nsec = (x - xsleep.tv_sec * 1000) * 1000 * 1000; \
nanosleep(&xsleep, NULL); \
} while (0)
#else #else
// Needed by Sleep() under Windows
# include <winbase.h> # include <winbase.h>
# define sleep Sleep # define msleep Sleep
# define SUSP_TIME 1 // msecs.
#endif #endif
@ -79,24 +80,37 @@ int main(int argc, const char *argv[])
if (argc >= 2) { if (argc >= 2) {
if ((input = fopen(argv[1], "r")) == NULL) { if ((input = fopen(argv[1], "r")) == NULL) {
ERR("%s", "Cannot open file."); ERR("%s", "Cannot open file.");
return EXIT_FAILURE; exit(EXIT_FAILURE);
} }
} }
nfc_context *context; nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
// Try to open the NFC reader // Try to open the NFC reader
pnd = nfc_open(context, NULL); pnd = nfc_open(context, NULL);
if (pnd == NULL) { if (pnd == NULL) {
ERR("%s", "Unable to open NFC device."); ERR("%s", "Unable to open NFC device.");
return EXIT_FAILURE; if (input != NULL) {
fclose(input);
}
nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("NFC reader: %s opened\n", nfc_device_get_name(pnd)); printf("NFC reader: %s opened\n", nfc_device_get_name(pnd));
if (nfc_initiator_init(pnd) < 0) { if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init"); nfc_perror(pnd, "nfc_initiator_init");
if (input != NULL) {
fclose(input);
}
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -141,15 +155,15 @@ int main(int argc, const char *argv[])
break; break;
} }
if (cmd[0] == 'p') { if (cmd[0] == 'p') {
int s = 0; int ms = 0;
offset++; offset++;
while (isspace(cmd[offset])) { while (isspace(cmd[offset])) {
offset++; offset++;
} }
sscanf(cmd + offset, "%d", &s); sscanf(cmd + offset, "%10d", &ms);
printf("Pause for %i msecs\n", s); printf("Pause for %i msecs\n", ms);
if (s > 0) { if (ms > 0) {
sleep(s * SUSP_TIME); msleep(ms);
} }
free(cmd); free(cmd);
continue; continue;
@ -199,5 +213,5 @@ int main(int argc, const char *argv[])
} }
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
return EXIT_SUCCESS; exit(EXIT_SUCCESS);
} }

View file

@ -101,7 +101,7 @@ extern "C" {
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, const size_t szRx, uint8_t *pbtRxPar); 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, const size_t szRx, 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, const size_t szRx, uint32_t *cycles); NFC_EXPORT int nfc_initiator_transceive_bytes_timed(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRx, 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, const size_t szRx, uint8_t *pbtRxPar, 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, const size_t szRx, uint8_t *pbtRxPar, uint32_t *cycles);
NFC_EXPORT int nfc_initiator_target_is_present(nfc_device *pnd, const nfc_target nt); NFC_EXPORT int nfc_initiator_target_is_present(nfc_device *pnd, const nfc_target *pnt);
/* NFC target: act as tag (i.e. MIFARE Classic) or NFC target device. */ /* NFC target: act as tag (i.e. MIFARE Classic) or NFC target device. */
NFC_EXPORT int nfc_target_init(nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRx, int timeout); NFC_EXPORT int nfc_target_init(nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRx, int timeout);
@ -138,7 +138,7 @@ extern "C" {
/* String converter functions */ /* String converter functions */
NFC_EXPORT const char *str_nfc_modulation_type(const nfc_modulation_type nmt); NFC_EXPORT const char *str_nfc_modulation_type(const nfc_modulation_type nmt);
NFC_EXPORT const char *str_nfc_baud_rate(const nfc_baud_rate nbr); NFC_EXPORT const char *str_nfc_baud_rate(const nfc_baud_rate nbr);
NFC_EXPORT int str_nfc_target(char **buf, const nfc_target nt, bool verbose); NFC_EXPORT int str_nfc_target(char **buf, const nfc_target *pnt, bool verbose);
/* Error codes */ /* Error codes */
/** @ingroup error /** @ingroup error

View file

@ -12,7 +12,11 @@ SET(CHIPS_SOURCES chips/pn53x)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/chips) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/chips)
# Library's buses # Library's buses
SET(BUSES_SOURCES buses/uart) IF(LIBUSB_FOUND)
SET(BUSES_SOURCES buses/uart buses/usbbus)
ELSE(LIBUSB_FOUND)
SET(BUSES_SOURCES buses/uart)
ENDIF(LIBUSB_FOUND)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/buses) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/buses)
INCLUDE(LibnfcDrivers) INCLUDE(LibnfcDrivers)
@ -42,7 +46,12 @@ SET(LIBRARY_SOURCES nfc nfc-device nfc-emulation nfc-internal conf iso14443-subr
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
IF(LIBNFC_LOG) IF(LIBNFC_LOG)
LIST(APPEND LIBRARY_SOURCES log-printf) IF(WIN32)
SET(CMAKE_C_FLAGS "-fgnu89-inline ${CMAKE_C_FLAGS}")
LIST(APPEND LIBRARY_SOURCES log-printf log_win32)
ELSE(WIN32)
LIST(APPEND LIBRARY_SOURCES log-printf log_posix)
ENDIF(WIN32)
ENDIF(LIBNFC_LOG) ENDIF(LIBNFC_LOG)
ADD_LIBRARY(nfc SHARED ${LIBRARY_SOURCES}) ADD_LIBRARY(nfc SHARED ${LIBRARY_SOURCES})

View file

@ -40,10 +40,11 @@ if LIBUSB_ENABLED
endif endif
if WITH_LOG if WITH_LOG
libnfc_la_SOURCES += log-printf.c libnfc_la_SOURCES += log-printf.c log_posix.c
endif endif
EXTRA_DIST = \ EXTRA_DIST = \
CMakeLists.txt \ CMakeLists.txt \
log-printf.c log-printf.c \
log_posix.c \
log_win32.c

View file

@ -1,10 +1,27 @@
# set the include path found by configure # set the include path found by configure
AM_CPPFLAGS = $(all_includes) $(LIBNFC_CFLAGS) AM_CPPFLAGS = $(all_includes) $(LIBNFC_CFLAGS)
noinst_LTLIBRARIES = libnfcbuses.la noinst_LTLIBRARIES = libnfcbuses.la
libnfcbuses_la_SOURCES = spi.c spi.h uart.c uart.h usbbus.c usbbus.h
libnfcbuses_la_SOURCES =
libnfcbuses_la_CFLAGS = -I$(top_srcdir)/libnfc libnfcbuses_la_CFLAGS = -I$(top_srcdir)/libnfc
libnfcbuses_la_LIBADD =
EXTRA_DIST = uart_posix.c uart_win32.c spi_posix.c # SPI_ENABLED
libnfcbuses_la_SOURCES += spi.c spi.h
libnfcbuses_la_CFLAGS +=
libnfcbuses_la_LIBADD +=
EXTRA_DIST = spi_posix.c
# UART_ENABLED
libnfcbuses_la_SOURCES += uart.c uart.h
libnfcbuses_la_CFLAGS +=
libnfcbuses_la_LIBADD +=
EXTRA_DIST = uart_posix.c uart_win32.c
if LIBUSB_ENABLED
libnfcbuses_la_SOURCES += usbbus.c usbbus.h
libnfcbuses_la_CFLAGS += @libusb_CFLAGS@
libnfcbuses_la_LIBADD += @libusb_LIBS@
endif
EXTRA_DIST += usbbus.c usbbus.h

View file

@ -30,7 +30,6 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/types.h>
#include <ctype.h> #include <ctype.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
@ -39,6 +38,7 @@
#include <stdio.h> #include <stdio.h>
#include <termios.h> #include <termios.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h>
#include "nfc-internal.h" #include "nfc-internal.h"
@ -127,7 +127,7 @@ uart_flush_input(serial_port sp)
} }
char *rx = malloc(available_bytes_count); char *rx = malloc(available_bytes_count);
// There is something available, read the data // There is something available, read the data
res = read(UART_DATA(sp)->fd, rx, available_bytes_count); (void)read(UART_DATA(sp)->fd, rx, available_bytes_count);
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%d bytes have eatten.", available_bytes_count); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%d bytes have eatten.", available_bytes_count);
free(rx); free(rx);
} }
@ -337,26 +337,32 @@ uart_list_ports(void)
size_t szRes = 1; size_t szRes = 1;
res[0] = NULL; res[0] = NULL;
DIR *dir;
DIR *pdDir = opendir("/dev"); if ((dir = opendir("/dev")) == NULL) {
struct dirent *pdDirEnt; perror("opendir error: /dev");
while ((pdDirEnt = readdir(pdDir)) != NULL) { return res;
}
struct dirent entry;
struct dirent *result;
while ((readdir_r(dir, &entry, &result) == 0) && (result != NULL)) {
#if !defined(__APPLE__) #if !defined(__APPLE__)
if (!isdigit(pdDirEnt->d_name[strlen(pdDirEnt->d_name) - 1])) if (!isdigit(entry.d_name[strlen(entry.d_name) - 1]))
continue; continue;
#endif #endif
const char **p = serial_ports_device_radix; const char **p = serial_ports_device_radix;
while (*p) { while (*p) {
if (!strncmp(pdDirEnt->d_name, *p, strlen(*p))) { if (!strncmp(entry.d_name, *p, strlen(*p))) {
char **res2 = realloc(res, (szRes + 1) * sizeof(char *)); char **res2 = realloc(res, (szRes + 1) * sizeof(char *));
if (!res2) if (!res2) {
perror("malloc");
goto oom; goto oom;
}
res = res2; res = res2;
if (!(res[szRes - 1] = malloc(6 + strlen(pdDirEnt->d_name)))) if (!(res[szRes - 1] = malloc(6 + strlen(entry.d_name)))) {
perror("malloc");
goto oom; goto oom;
}
sprintf(res[szRes - 1], "/dev/%s", pdDirEnt->d_name); sprintf(res[szRes - 1], "/dev/%s", entry.d_name);
szRes++; szRes++;
res[szRes - 1] = NULL; res[szRes - 1] = NULL;
@ -365,7 +371,7 @@ uart_list_ports(void)
} }
} }
oom: oom:
closedir(pdDir); closedir(dir);
return res; return res;
} }

View file

@ -24,6 +24,7 @@
* @brief Windows UART driver * @brief Windows UART driver
*/ */
#include <inttypes.h>
#include "log.h" #include "log.h"
#define LOG_GROUP NFC_LOG_GROUP_COM #define LOG_GROUP NFC_LOG_GROUP_COM
@ -164,7 +165,7 @@ uart_receive(serial_port sp, uint8_t *pbtRx, const size_t szRx, void *abort_p, i
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to apply new timeout settings."); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to apply new timeout settings.");
return NFC_EIO; return NFC_EIO;
} }
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Timeouts are set to %u ms", timeout_ms); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Timeouts are set to %lu ms", timeout_ms);
// TODO Enhance the reception method // TODO Enhance the reception method
// - According to MSDN, it could be better to implement nfc_abort_command() mecanism using Cancello() // - According to MSDN, it could be better to implement nfc_abort_command() mecanism using Cancello()
@ -179,7 +180,7 @@ uart_receive(serial_port sp, uint8_t *pbtRx, const size_t szRx, void *abort_p, i
if (!res) { if (!res) {
DWORD err = GetLastError(); DWORD err = GetLastError();
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "ReadFile error: %u", err); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "ReadFile error: %lu", err);
return NFC_EIO; return NFC_EIO;
} else if (dwBytesReceived == 0) { } else if (dwBytesReceived == 0) {
return NFC_ETIMEOUT; return NFC_ETIMEOUT;

View file

@ -28,6 +28,7 @@
# include "config.h" # include "config.h"
#endif // HAVE_CONFIG_H #endif // HAVE_CONFIG_H
#include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -317,9 +318,9 @@ pn53x_set_parameters(struct nfc_device *pnd, const uint8_t ui8Parameter, const b
int int
pn53x_set_tx_bits(struct nfc_device *pnd, const uint8_t ui8Bits) 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 // Test if we need to update the transmission bits register setting
if (CHIP_DATA(pnd)->ui8TxBits != ui8Bits) { if (CHIP_DATA(pnd)->ui8TxBits != ui8Bits) {
int res = 0;
// Set the amount of transmission bits in the PN53X chip register // Set the amount of transmission bits in the PN53X chip register
if ((res = pn53x_write_register(pnd, PN53X_REG_CIU_BitFraming, SYMBOL_TX_LAST_BITS, ui8Bits)) < 0) if ((res = pn53x_write_register(pnd, PN53X_REG_CIU_BitFraming, SYMBOL_TX_LAST_BITS, ui8Bits)) < 0)
return res; return res;
@ -613,10 +614,10 @@ pn53x_WriteRegister(struct nfc_device *pnd, const uint16_t ui16RegisterAddress,
int int
pn53x_write_register(struct nfc_device *pnd, const uint16_t ui16RegisterAddress, const uint8_t ui8SymbolMask, const uint8_t ui8Value) 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)) { if ((ui16RegisterAddress < PN53X_CACHE_REGISTER_MIN_ADDRESS) || (ui16RegisterAddress > PN53X_CACHE_REGISTER_MAX_ADDRESS)) {
// Direct write // Direct write
if (ui8SymbolMask != 0xff) { if (ui8SymbolMask != 0xff) {
int res = 0;
uint8_t ui8CurrentValue; uint8_t ui8CurrentValue;
if ((res = pn53x_read_register(pnd, ui16RegisterAddress, &ui8CurrentValue)) < 0) if ((res = pn53x_read_register(pnd, ui16RegisterAddress, &ui8CurrentValue)) < 0)
return res; return res;
@ -1354,7 +1355,7 @@ pn53x_initiator_transceive_bytes(struct nfc_device *pnd, const uint8_t *pbtTx, c
const size_t szRxLen = (size_t)res - 1; const size_t szRxLen = (size_t)res - 1;
if (pbtRx != NULL) { if (pbtRx != NULL) {
if (szRxLen > szRx) { if (szRxLen > szRx) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Buffer size is too short: %zuo available(s), %zuo needed", szRx, szRxLen); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Buffer size is too short: %" PRIuPTR " available(s), %" PRIuPTR " needed", szRx, szRxLen);
return NFC_EOVFLOW; return NFC_EOVFLOW;
} }
// Copy the received bytes // Copy the received bytes
@ -1629,7 +1630,7 @@ pn53x_initiator_transceive_bytes_timed(struct nfc_device *pnd, const uint8_t *pb
} }
if (pbtRx != NULL) { if (pbtRx != NULL) {
if ((szRxLen + sz) > szRx) { if ((szRxLen + sz) > szRx) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Buffer size is too short: %zuo available(s), %zuo needed", szRx, szRxLen + sz); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Buffer size is too short: %" PRIuPTR " available(s), %" PRIuPTR " needed", szRx, szRxLen + sz);
return NFC_EOVFLOW; return NFC_EOVFLOW;
} }
// Copy the received bytes // Copy the received bytes
@ -1668,10 +1669,10 @@ pn53x_initiator_deselect_target(struct nfc_device *pnd)
} }
int int
pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target nt) pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt)
{ {
// Check if the argument target nt is equals to current saved target // Check if the argument target nt is equals to current saved target
if (!pn53x_current_target_is(pnd, &nt)) { if (!pn53x_current_target_is(pnd, pnt)) {
return NFC_ETGRELEASED; return NFC_ETGRELEASED;
} }
@ -2711,7 +2712,7 @@ pn53x_build_frame(uint8_t *pbtFrame, size_t *pszFrame, const uint8_t *pbtData, c
(*pszFrame) = szData + PN53x_EXTENDED_FRAME__OVERHEAD; (*pszFrame) = szData + PN53x_EXTENDED_FRAME__OVERHEAD;
} else { } else {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "We can't send more than %d bytes in a raw (requested: %zd)", PN53x_EXTENDED_FRAME__DATA_MAX_LEN, szData); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "We can't send more than %d bytes in a raw (requested: %" PRIdPTR ")", PN53x_EXTENDED_FRAME__DATA_MAX_LEN, szData);
return NFC_ECHIP; return NFC_ECHIP;
} }
return NFC_SUCCESS; return NFC_SUCCESS;

View file

@ -337,7 +337,7 @@ int pn53x_initiator_transceive_bits_timed(struct nfc_device *pnd, const uint8
int pn53x_initiator_transceive_bytes_timed(struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int pn53x_initiator_transceive_bytes_timed(struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx,
uint8_t *pbtRx, const size_t szRx, uint32_t *cycles); uint8_t *pbtRx, const size_t szRx, uint32_t *cycles);
int pn53x_initiator_deselect_target(struct nfc_device *pnd); int pn53x_initiator_deselect_target(struct nfc_device *pnd);
int pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target nt); int pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt);
// NFC device as Target functions // NFC device as Target functions
int pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRxLen, int timeout); int pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRxLen, int timeout);

View file

@ -1,3 +1,4 @@
/*- /*-
* Copyright (C) 2012, 2013 Romuald Conty * Copyright (C) 2012, 2013 Romuald Conty
* *
@ -15,12 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/> * along with this program. If not, see <http://www.gnu.org/licenses/>
*/ */
#include "conf.h"
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include "config.h" # include "config.h"
#endif // HAVE_CONFIG_H #endif // HAVE_CONFIG_H
#include "conf.h"
#ifdef CONFFILES #ifdef CONFFILES
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -163,7 +164,10 @@ conf_devices_load(const char *dirname, nfc_context *context)
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Unable to open directory: %s", dirname); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Unable to open directory: %s", dirname);
} else { } else {
struct dirent *de; struct dirent *de;
while ((de = readdir(d))) { struct dirent entry;
struct dirent *result;
while ((readdir_r(d, &entry, &result) == 0) && (result != NULL)) {
de = &entry;
if (de->d_name[0] != '.') { if (de->d_name[0] != '.') {
const size_t filename_len = strlen(de->d_name); const size_t filename_len = strlen(de->d_name);
const size_t extension_len = strlen(".conf"); const size_t extension_len = strlen(".conf");

View file

@ -14,7 +14,12 @@
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> * along with this program. If not, see <http://www.gnu.org/licenses/>
*/ */
#include "nfc-internal.h" #ifndef __NFC_CONF_H__
#define __NFC_CONF_H__
#include <nfc/nfc-types.h>
void conf_load(nfc_context *context); void conf_load(nfc_context *context);
#endif // __NFC_CONF_H__

View file

@ -227,9 +227,6 @@ acr122_pcsc_connstring_decode(const nfc_connstring connstring, struct acr122_pcs
free(cs); free(cs);
return 2; return 2;
free(cs);
return 3;
} }
static nfc_device * static nfc_device *
@ -258,7 +255,7 @@ acr122_pcsc_open(const nfc_context *context, const nfc_connstring connstring)
if (strlen(ndd.pcsc_device_name) < 5) { // We can assume it's a reader ID as pcsc_name always ends with "NN NN" if (strlen(ndd.pcsc_device_name) < 5) { // We can assume it's a reader ID as pcsc_name always ends with "NN NN"
// Device was not specified, only ID, retrieve it // Device was not specified, only ID, retrieve it
size_t index; size_t index;
if (sscanf(ndd.pcsc_device_name, "%lu", &index) != 1) if (sscanf(ndd.pcsc_device_name, "%4" SCNuPTR, &index) != 1)
return NULL; return NULL;
nfc_connstring *ncs = malloc(sizeof(nfc_connstring) * (index + 1)); nfc_connstring *ncs = malloc(sizeof(nfc_connstring) * (index + 1));
if (!ncs) { if (!ncs) {
@ -271,6 +268,7 @@ acr122_pcsc_open(const nfc_context *context, const nfc_connstring connstring)
return NULL; return NULL;
} }
strncpy(fullconnstring, ncs[index], sizeof(nfc_connstring)); strncpy(fullconnstring, ncs[index], sizeof(nfc_connstring));
fullconnstring[sizeof(nfc_connstring) - 1] = '\0';
free(ncs); free(ncs);
connstring_decode_level = acr122_pcsc_connstring_decode(fullconnstring, &ndd); connstring_decode_level = acr122_pcsc_connstring_decode(fullconnstring, &ndd);
if (connstring_decode_level < 2) { if (connstring_decode_level < 2) {
@ -280,6 +278,10 @@ acr122_pcsc_open(const nfc_context *context, const nfc_connstring connstring)
char *pcFirmware; char *pcFirmware;
nfc_device *pnd = nfc_device_new(context, fullconnstring); nfc_device *pnd = nfc_device_new(context, fullconnstring);
if (!pnd) {
perror("malloc");
goto error;
}
pnd->driver_data = malloc(sizeof(struct acr122_pcsc_data)); pnd->driver_data = malloc(sizeof(struct acr122_pcsc_data));
if (!pnd->driver_data) { if (!pnd->driver_data) {
perror("malloc"); perror("malloc");

View file

@ -372,7 +372,9 @@ acr122_usb_connstring_decode(const nfc_connstring connstring, struct acr122_usb_
driver_name[0] = '\0'; driver_name[0] = '\0';
int res = sscanf(connstring, "%[^:]:%[^:]:%[^:]", driver_name, dirname, filename); char format[32];
snprintf(format, sizeof(format), "%%%i[^:]:%%%i[^:]:%%%i[^:]", n - 1, n - 1, n - 1);
int res = sscanf(connstring, format, driver_name, dirname, filename);
if (!res || ((0 != strcmp(driver_name, ACR122_USB_DRIVER_NAME)) && (0 != strcmp(driver_name, "usb")))) { if (!res || ((0 != strcmp(driver_name, ACR122_USB_DRIVER_NAME)) && (0 != strcmp(driver_name, "usb")))) {
// Driver name does not match. // Driver name does not match.
@ -408,6 +410,7 @@ acr122_usb_get_usb_device_name(struct usb_device *dev, usb_dev_handle *udev, cha
if ((acr122_usb_supported_devices[n].vendor_id == dev->descriptor.idVendor) && if ((acr122_usb_supported_devices[n].vendor_id == dev->descriptor.idVendor) &&
(acr122_usb_supported_devices[n].product_id == dev->descriptor.idProduct)) { (acr122_usb_supported_devices[n].product_id == dev->descriptor.idProduct)) {
strncpy(buffer, acr122_usb_supported_devices[n].name, len); strncpy(buffer, acr122_usb_supported_devices[n].name, len);
buffer[len - 1] = '\0';
return true; return true;
} }
} }
@ -475,6 +478,10 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring)
data.model = acr122_usb_get_device_model(dev->descriptor.idVendor, dev->descriptor.idProduct); data.model = acr122_usb_get_device_model(dev->descriptor.idVendor, dev->descriptor.idProduct);
// Allocate memory for the device info and specification, fill it and return the info // Allocate memory for the device info and specification, fill it and return the info
pnd = nfc_device_new(context, connstring); pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
goto error;
}
acr122_usb_get_usb_device_name(dev, data.pudh, pnd->name, sizeof(pnd->name)); acr122_usb_get_usb_device_name(dev, data.pudh, pnd->name, sizeof(pnd->name));
pnd->driver_data = malloc(sizeof(struct acr122_usb_data)); pnd->driver_data = malloc(sizeof(struct acr122_usb_data));
@ -547,13 +554,7 @@ uint32_t htole32(uint32_t u32);
uint32_t uint32_t
htole32(uint32_t u32) htole32(uint32_t u32)
{ {
uint8_t u8[4]; return (((u32 & 0xff) << 24) + ((u32 & 0xff00) << 8) + ((u32 & 0xff0000) >> 8) + (u32 >> 24));
for (int i = 0; i < 4; i++) {
u8[i] = (u32 & 0xff);
u32 >>= 8;
}
uint32_t *pu32 = (uint32_t *)u8;
return *pu32;
} }
static int static int
@ -717,7 +718,7 @@ read:
len -= 4; // We skip 2 bytes for PN532 direction byte (D5) and command byte (CMD+1), then 2 bytes for APDU status (90 00). len -= 4; // We skip 2 bytes for PN532 direction byte (D5) and command byte (CMD+1), then 2 bytes for APDU status (90 00).
if (len > szDataLen) { if (len > szDataLen) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %" PRIuPTR ", len: %" PRIuPTR ")", szDataLen, len);
pnd->last_error = NFC_EOVFLOW; pnd->last_error = NFC_EOVFLOW;
return pnd->last_error; return pnd->last_error;
} }

View file

@ -438,7 +438,7 @@ acr122s_connstring_decode(const nfc_connstring connstring, struct acr122s_descri
return 2; return 2;
} }
unsigned long speed; unsigned long speed;
if (sscanf(speed_s, "%lu", &speed) != 1) { if (sscanf(speed_s, "%10lu", &speed) != 1) {
// speed_s is not a number // speed_s is not a number
free(cs); free(cs);
return 2; return 2;
@ -470,6 +470,10 @@ acr122s_scan(const nfc_context *context, nfc_connstring connstrings[], const siz
nfc_connstring connstring; nfc_connstring connstring;
snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, ACR122S_DRIVER_NAME, acPort, ACR122S_DEFAULT_SPEED); snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, ACR122S_DRIVER_NAME, acPort, ACR122S_DEFAULT_SPEED);
nfc_device *pnd = nfc_device_new(context, connstring); nfc_device *pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
return -1;
}
pnd->driver = &acr122s_driver; pnd->driver = &acr122s_driver;
pnd->driver_data = malloc(sizeof(struct acr122s_data)); pnd->driver_data = malloc(sizeof(struct acr122s_data));
@ -574,6 +578,10 @@ acr122s_open(const nfc_context *context, const nfc_connstring connstring)
uart_set_speed(sp, ndd.speed); uart_set_speed(sp, ndd.speed);
pnd = nfc_device_new(context, connstring); pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
return NULL;
}
pnd->driver = &acr122s_driver; pnd->driver = &acr122s_driver;
strcpy(pnd->name, ACR122S_DRIVER_NAME); strcpy(pnd->name, ACR122S_DRIVER_NAME);
@ -676,7 +684,7 @@ acr122s_receive(nfc_device *pnd, uint8_t *buf, size_t buf_len, int timeout)
size_t data_len = FRAME_SIZE(tmp) - 17; size_t data_len = FRAME_SIZE(tmp) - 17;
if (data_len > buf_len) { if (data_len > buf_len) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Receive buffer too small. (buf_len: %zu, data_len: %zu)", buf_len, data_len); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Receive buffer too small. (buf_len: %" PRIuPTR ", data_len: %" PRIuPTR ")", buf_len, data_len);
pnd->last_error = NFC_EIO; pnd->last_error = NFC_EIO;
return pnd->last_error; return pnd->last_error;
} }

View file

@ -114,6 +114,10 @@ arygon_scan(const nfc_context *context, nfc_connstring connstrings[], const size
nfc_connstring connstring; nfc_connstring connstring;
snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, ARYGON_DRIVER_NAME, acPort, ARYGON_DEFAULT_SPEED); snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, ARYGON_DRIVER_NAME, acPort, ARYGON_DEFAULT_SPEED);
nfc_device *pnd = nfc_device_new(context, connstring); nfc_device *pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
return 0;
}
pnd->driver = &arygon_driver; pnd->driver = &arygon_driver;
pnd->driver_data = malloc(sizeof(struct arygon_data)); pnd->driver_data = malloc(sizeof(struct arygon_data));
@ -203,7 +207,7 @@ arygon_connstring_decode(const nfc_connstring connstring, struct arygon_descript
return 2; return 2;
} }
unsigned long speed; unsigned long speed;
if (sscanf(speed_s, "%lu", &speed) != 1) { if (sscanf(speed_s, "%10lu", &speed) != 1) {
// speed_s is not a number // speed_s is not a number
free(cs); free(cs);
return 2; return 2;
@ -263,6 +267,10 @@ arygon_open(const nfc_context *context, const nfc_connstring connstring)
// We have a connection // We have a connection
pnd = nfc_device_new(context, connstring); pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
return NULL;
}
snprintf(pnd->name, sizeof(pnd->name), "%s:%s", ARYGON_DRIVER_NAME, ndd.port); snprintf(pnd->name, sizeof(pnd->name), "%s:%s", ARYGON_DRIVER_NAME, ndd.port);
pnd->driver_data = malloc(sizeof(struct arygon_data)); pnd->driver_data = malloc(sizeof(struct arygon_data));
@ -322,7 +330,7 @@ arygon_tama_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, i
size_t szFrame = 0; size_t szFrame = 0;
if (szData > PN53x_NORMAL_FRAME__DATA_MAX_LEN) { if (szData > PN53x_NORMAL_FRAME__DATA_MAX_LEN) {
// ARYGON Reader with PN532 equipped does not support extended frame (bug in ARYGON firmware?) // ARYGON Reader with PN532 equipped does not support extended frame (bug in ARYGON firmware?)
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "ARYGON device does not support more than %d bytes as payload (requested: %zd)", PN53x_NORMAL_FRAME__DATA_MAX_LEN, szData); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "ARYGON device does not support more than %d bytes as payload (requested: %" PRIdPTR ")", PN53x_NORMAL_FRAME__DATA_MAX_LEN, szData);
pnd->last_error = NFC_EDEVNOTSUPP; pnd->last_error = NFC_EDEVNOTSUPP;
return pnd->last_error; return pnd->last_error;
} }
@ -430,7 +438,7 @@ arygon_tama_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, i
} }
if (len > szDataLen) { if (len > szDataLen) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %" PRIuPTR ", len: %" PRIuPTR ")", szDataLen, len);
pnd->last_error = NFC_EIO; pnd->last_error = NFC_EIO;
return pnd->last_error; return pnd->last_error;
} }
@ -511,7 +519,9 @@ arygon_firmware(nfc_device *pnd, char *str)
if (0 == memcmp(abtRx, arygon_error_none, 6)) { if (0 == memcmp(abtRx, arygon_error_none, 6)) {
uint8_t *p = abtRx + 6; uint8_t *p = abtRx + 6;
unsigned int szData; unsigned int szData;
sscanf((const char *)p, "%02x%s", &szData, p); sscanf((const char *)p, "%02x%9s", &szData, p);
if (szData > 9)
szData = 9;
memcpy(str, p, szData); memcpy(str, p, szData);
*(str + szData) = '\0'; *(str + szData) = '\0';
} }

View file

@ -88,6 +88,10 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
nfc_connstring connstring; nfc_connstring connstring;
snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, PN532_UART_DRIVER_NAME, acPort, PN532_UART_DEFAULT_SPEED); snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, PN532_UART_DRIVER_NAME, acPort, PN532_UART_DEFAULT_SPEED);
nfc_device *pnd = nfc_device_new(context, connstring); nfc_device *pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
return 0;
}
pnd->driver = &pn532_uart_driver; pnd->driver = &pn532_uart_driver;
pnd->driver_data = malloc(sizeof(struct pn532_uart_data)); pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
if (!pnd->driver_data) { if (!pnd->driver_data) {
@ -180,7 +184,7 @@ pn532_connstring_decode(const nfc_connstring connstring, struct pn532_uart_descr
return 2; return 2;
} }
unsigned long speed; unsigned long speed;
if (sscanf(speed_s, "%lu", &speed) != 1) { if (sscanf(speed_s, "%10lu", &speed) != 1) {
// speed_s is not a number // speed_s is not a number
free(cs); free(cs);
return 2; return 2;
@ -240,6 +244,10 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring)
// We have a connection // We have a connection
pnd = nfc_device_new(context, connstring); pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
return NULL;
}
snprintf(pnd->name, sizeof(pnd->name), "%s:%s", PN532_UART_DRIVER_NAME, ndd.port); snprintf(pnd->name, sizeof(pnd->name), "%s:%s", PN532_UART_DRIVER_NAME, ndd.port);
pnd->driver_data = malloc(sizeof(struct pn532_uart_data)); pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
@ -416,7 +424,7 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in
} }
if (len > szDataLen) { if (len > szDataLen) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %" PRIuPTR ", len: %" PRIuPTR ")", szDataLen, len);
pnd->last_error = NFC_EIO; pnd->last_error = NFC_EIO;
goto error; goto error;
} }
@ -481,8 +489,8 @@ error:
int int
pn532_uart_ack(nfc_device *pnd) pn532_uart_ack(nfc_device *pnd)
{ {
int res = 0;
if (POWERDOWN == CHIP_DATA(pnd)->power_mode) { if (POWERDOWN == CHIP_DATA(pnd)->power_mode) {
int res = 0;
if ((res = pn532_uart_wakeup(pnd)) < 0) { if ((res = pn532_uart_wakeup(pnd)) < 0) {
return res; return res;
} }

View file

@ -257,7 +257,9 @@ pn53x_usb_connstring_decode(const nfc_connstring connstring, struct pn53x_usb_de
driver_name[0] = '\0'; driver_name[0] = '\0';
int res = sscanf(connstring, "%[^:]:%[^:]:%[^:]", driver_name, dirname, filename); char format[32];
snprintf(format, sizeof(format), "%%%i[^:]:%%%i[^:]:%%%i[^:]", n - 1, n - 1, n - 1);
int res = sscanf(connstring, format, driver_name, dirname, filename);
if (!res || ((0 != strcmp(driver_name, PN53X_USB_DRIVER_NAME)) && (0 != strcmp(driver_name, "usb")))) { if (!res || ((0 != strcmp(driver_name, PN53X_USB_DRIVER_NAME)) && (0 != strcmp(driver_name, "usb")))) {
// Driver name does not match. // Driver name does not match.
@ -293,6 +295,7 @@ pn53x_usb_get_usb_device_name(struct usb_device *dev, usb_dev_handle *udev, char
if ((pn53x_usb_supported_devices[n].vendor_id == dev->descriptor.idVendor) && if ((pn53x_usb_supported_devices[n].vendor_id == dev->descriptor.idVendor) &&
(pn53x_usb_supported_devices[n].product_id == dev->descriptor.idProduct)) { (pn53x_usb_supported_devices[n].product_id == dev->descriptor.idProduct)) {
strncpy(buffer, pn53x_usb_supported_devices[n].name, len); strncpy(buffer, pn53x_usb_supported_devices[n].name, len);
buffer[len - 1] = '\0';
return true; return true;
} }
} }
@ -360,6 +363,10 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring)
data.model = pn53x_usb_get_device_model(dev->descriptor.idVendor, dev->descriptor.idProduct); 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 // Allocate memory for the device info and specification, fill it and return the info
pnd = nfc_device_new(context, connstring); pnd = nfc_device_new(context, connstring);
if (!pnd) {
perror("malloc");
goto error;
}
pn53x_usb_get_usb_device_name(dev, data.pudh, pnd->name, sizeof(pnd->name)); pn53x_usb_get_usb_device_name(dev, data.pudh, pnd->name, sizeof(pnd->name));
pnd->driver_data = malloc(sizeof(struct pn53x_usb_data)); pnd->driver_data = malloc(sizeof(struct pn53x_usb_data));
@ -581,7 +588,7 @@ read:
} }
if (len > szDataLen) { if (len > szDataLen) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %" PRIuPTR ", len: %" PRIuPTR ")", szDataLen, len);
pnd->last_error = NFC_EIO; pnd->last_error = NFC_EIO;
return pnd->last_error; return pnd->last_error;
} }

View file

@ -1,6 +1,7 @@
/*- /*-
* Copyright (C) 2011 Romain Tartière * Copyright (C) 2011 Romain Tartière
* Copyright (C) 2011, 2012 Romuald Conty * Copyright (C) 2011, 2012 Romuald Conty
* Copyright (C) 2013 Alex Lian
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the * under the terms of the GNU Lesser General Public License as published by the
@ -31,6 +32,12 @@
#error "No logging defined, but log-printf.c still compiled." #error "No logging defined, but log-printf.c still compiled."
#else // LOG #else // LOG
// Internal methods so different platforms can route the logging
// Offering both forms of the variadic function
// These are implemented in the log_<platform> specific file
void log_put_internal(const char *format, ...);
void log_vput_internal(const char *format, va_list args);
void void
log_init(const nfc_context *context) log_init(const nfc_context *context)
{ {
@ -71,11 +78,12 @@ log_put(const uint8_t group, const char *category, const uint8_t priority, const
if (log_level) { // If log is not disabled by log_level=none if (log_level) { // If log is not disabled by log_level=none
if (((log_level & 0x00000003) >= priority) || // Global log level if (((log_level & 0x00000003) >= priority) || // Global log level
(((log_level >> (group * 2)) & 0x00000003) >= priority)) { // Group log level (((log_level >> (group * 2)) & 0x00000003) >= priority)) { // Group log level
va_list va; va_list va;
va_start(va, format); va_start(va, format);
fprintf(stderr, "%s\t%s\t", log_priority_to_str(priority), category); log_put_internal("%s\t%s\t", log_priority_to_str(priority), category);
vfprintf(stderr, format, va); log_vput_internal(format, va);
fprintf(stderr, "\n"); log_put_internal("\n");
va_end(va); va_end(va);
} }
} }

41
libnfc/log_posix.c Normal file
View file

@ -0,0 +1,41 @@
/*-
* Copyright (C) 2011 Romain Tartière
* Copyright (C) 2011, 2012 Romuald Conty
* Copyright (C) 2013 Alex Lian
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "log.h"
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdarg.h>
void
log_vput_internal(const char *format, va_list args)
{
vfprintf(stderr, format, args);
}
void
log_put_internal(const char *format, ...)
{
va_list va;
va_start(va, format);
vfprintf(stderr, format, va);
va_end(va);
}

56
libnfc/log_win32.c Normal file
View file

@ -0,0 +1,56 @@
/*-
* Copyright (C) 2011 Romain Tartière
* Copyright (C) 2011, 2012 Romuald Conty
* Copyright (C) 2013 Alex Lian
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "log.h"
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdarg.h>
#include <strsafe.h>
void
log_output_debug(const char *format, va_list args)
{
char buffer[1024];
HRESULT hr = StringCbVPrintf(buffer, sizeof(buffer), format, args);
// Spew what we got, even if the buffer is not sized large enough
if ((STRSAFE_E_INSUFFICIENT_BUFFER == hr) || (S_OK == hr))
OutputDebugString(buffer);
}
void
log_vput_internal(const char *format, va_list args)
{
vfprintf(stderr, format, args);
// Additional windows output to the debug window for debugging purposes
log_output_debug(format, args);
}
void
log_put_internal(const char *format, ...)
{
va_list va;
va_start(va, format);
vfprintf(stderr, format, va);
// Additional windows output to the debug window for debugging purposes
log_output_debug(format, va);
va_end(va);
}

View file

@ -38,7 +38,7 @@ nfc_device_new(const nfc_context *context, const nfc_connstring connstring)
nfc_device *res = malloc(sizeof(*res)); nfc_device *res = malloc(sizeof(*res));
if (!res) { if (!res) {
err(EXIT_FAILURE, "nfc_device_new: malloc"); return NULL;
} }
// Store associated context // Store associated context

View file

@ -68,7 +68,7 @@ nfc_context_new(void)
nfc_context *res = malloc(sizeof(*res)); nfc_context *res = malloc(sizeof(*res));
if (!res) { if (!res) {
err(EXIT_FAILURE, "nfc_context_new: malloc"); return NULL;
} }
// Set default context values // Set default context values

View file

@ -131,7 +131,7 @@ struct nfc_driver {
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_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, const size_t szRx, uint32_t *cycles); int (*initiator_transceive_bytes_timed)(struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRx, 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); 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);
int (*initiator_target_is_present)(struct nfc_device *pnd, const nfc_target nt); int (*initiator_target_is_present)(struct nfc_device *pnd, const nfc_target *pnt);
int (*target_init)(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRx, int timeout); 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_send_bytes)(struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int timeout);

View file

@ -179,7 +179,10 @@ void
nfc_init(nfc_context **context) nfc_init(nfc_context **context)
{ {
*context = nfc_context_new(); *context = nfc_context_new();
if (!*context) {
perror("malloc");
return;
}
if (!nfc_drivers) if (!nfc_drivers)
nfc_drivers_init(); nfc_drivers_init();
} }
@ -230,6 +233,7 @@ nfc_open(nfc_context *context, const nfc_connstring connstring)
} }
} else { } else {
strncpy(ncs, connstring, sizeof(nfc_connstring)); strncpy(ncs, connstring, sizeof(nfc_connstring));
ncs[sizeof(nfc_connstring) - 1] = '\0';
} }
// Search through the device list for an available device // Search through the device list for an available device
@ -357,9 +361,8 @@ nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_
const struct nfc_driver_list *pndl = nfc_drivers; const struct nfc_driver_list *pndl = nfc_drivers;
while (pndl) { while (pndl) {
const struct nfc_driver *ndr = pndl->driver; const struct nfc_driver *ndr = pndl->driver;
size_t _device_found = 0;
if ((ndr->scan_type == NOT_INTRUSIVE) || ((context->allow_intrusive_scan) && (ndr->scan_type == INTRUSIVE))) { if ((ndr->scan_type == NOT_INTRUSIVE) || ((context->allow_intrusive_scan) && (ndr->scan_type == INTRUSIVE))) {
_device_found = ndr->scan(context, connstrings + (device_found), connstrings_len - (device_found)); size_t _device_found = ndr->scan(context, connstrings + (device_found), connstrings_len - (device_found));
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%ld device(s) found using %s driver", (unsigned long) _device_found, ndr->name); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%ld device(s) found using %s driver", (unsigned long) _device_found, ndr->name);
if (_device_found > 0) { if (_device_found > 0) {
device_found += _device_found; device_found += _device_found;
@ -825,9 +828,9 @@ nfc_initiator_transceive_bytes_timed(nfc_device *pnd,
* @warning To run the test, one or more commands will be sent to target * @warning To run the test, one or more commands will be sent to target
*/ */
int int
nfc_initiator_target_is_present(nfc_device *pnd, const nfc_target nt) nfc_initiator_target_is_present(nfc_device *pnd, const nfc_target *pnt)
{ {
HAL(initiator_target_is_present, pnd, nt); HAL(initiator_target_is_present, pnd, pnt);
} }
/** @ingroup initiator /** @ingroup initiator
@ -1291,12 +1294,12 @@ str_nfc_modulation_type(const nfc_modulation_type nmt)
* @warning *buf must be freed using nfc_free() * @warning *buf must be freed using nfc_free()
*/ */
int int
str_nfc_target(char **buf, const nfc_target nt, bool verbose) str_nfc_target(char **buf, const nfc_target *pnt, bool verbose)
{ {
*buf = malloc(4096); *buf = malloc(4096);
if (! *buf) if (! *buf)
return NFC_ESOFT; return NFC_ESOFT;
(*buf)[0] = '\0'; (*buf)[0] = '\0';
sprint_nfc_target(*buf, nt, verbose); snprint_nfc_target(*buf, 4096, pnt, verbose);
return strlen(*buf); return strlen(*buf);
} }

View file

@ -23,6 +23,7 @@
* @file target-subr.c * @file target-subr.c
* @brief Target-related subroutines. (ie. determine target type, print target, etc.) * @brief Target-related subroutines. (ie. determine target type, print target, etc.)
*/ */
#include <inttypes.h>
#include <nfc/nfc.h> #include <nfc/nfc.h>
#include "target-subr.h" #include "target-subr.h"
@ -117,15 +118,14 @@ struct card_sak const_cs[] = {
}; };
int int
sprint_hex(char *dst, const uint8_t *pbtData, const size_t szBytes) snprint_hex(char *dst, size_t size, const uint8_t *pbtData, const size_t szBytes)
{ {
size_t szPos; size_t szPos;
size_t res = 0;
int res = 0;
for (szPos = 0; szPos < szBytes; szPos++) { for (szPos = 0; szPos < szBytes; szPos++) {
res += sprintf(dst + res, "%02x ", pbtData[szPos]); res += snprintf(dst + res, size - res, "%02x ", pbtData[szPos]);
} }
res += sprintf(dst + res, "\n"); res += snprintf(dst + res, size - res, "\n");
return res; return res;
} }
@ -134,282 +134,283 @@ sprint_hex(char *dst, const uint8_t *pbtData, const size_t szBytes)
#define SAK_ISO18092_COMPLIANT 0x40 #define SAK_ISO18092_COMPLIANT 0x40
void void
sprint_nfc_iso14443a_info(char *dst, const nfc_iso14443a_info nai, bool verbose) snprint_nfc_iso14443a_info(char *dst, size_t size, const nfc_iso14443a_info *pnai, bool verbose)
{ {
dst += sprintf(dst, " ATQA (SENS_RES): "); int off = 0;
dst += sprint_hex(dst, nai.abtAtqa, 2); off += snprintf(dst + off, size - off, " ATQA (SENS_RES): ");
off += snprint_hex(dst + off, size - off, pnai->abtAtqa, 2);
if (verbose) { if (verbose) {
dst += sprintf(dst, "* UID size: "); off += snprintf(dst + off, size - off, "* UID size: ");
switch ((nai.abtAtqa[1] & 0xc0) >> 6) { switch ((pnai->abtAtqa[1] & 0xc0) >> 6) {
case 0: case 0:
dst += sprintf(dst, "single\n"); off += snprintf(dst + off, size - off, "single\n");
break; break;
case 1: case 1:
dst += sprintf(dst, "double\n"); off += snprintf(dst + off, size - off, "double\n");
break; break;
case 2: case 2:
dst += sprintf(dst, "triple\n"); off += snprintf(dst + off, size - off, "triple\n");
break; break;
case 3: case 3:
dst += sprintf(dst, "RFU\n"); off += snprintf(dst + off, size - off, "RFU\n");
break; break;
} }
dst += sprintf(dst, "* bit frame anticollision "); off += snprintf(dst + off, size - off, "* bit frame anticollision ");
switch (nai.abtAtqa[1] & 0x1f) { switch (pnai->abtAtqa[1] & 0x1f) {
case 0x01: case 0x01:
case 0x02: case 0x02:
case 0x04: case 0x04:
case 0x08: case 0x08:
case 0x10: case 0x10:
dst += sprintf(dst, "supported\n"); off += snprintf(dst + off, size - off, "supported\n");
break; break;
default: default:
dst += sprintf(dst, "not supported\n"); off += snprintf(dst + off, size - off, "not supported\n");
break; break;
} }
} }
dst += sprintf(dst, " UID (NFCID%c): ", (nai.abtUid[0] == 0x08 ? '3' : '1')); off += snprintf(dst + off, size - off, " UID (NFCID%c): ", (pnai->abtUid[0] == 0x08 ? '3' : '1'));
dst += sprint_hex(dst, nai.abtUid, nai.szUidLen); off += snprint_hex(dst + off, size - off, pnai->abtUid, pnai->szUidLen);
if (verbose) { if (verbose) {
if (nai.abtUid[0] == 0x08) { if (pnai->abtUid[0] == 0x08) {
dst += sprintf(dst, "* Random UID\n"); off += snprintf(dst + off, size - off, "* Random UID\n");
} }
} }
dst += sprintf(dst, " SAK (SEL_RES): "); off += snprintf(dst + off, size - off, " SAK (SEL_RES): ");
dst += sprint_hex(dst, &nai.btSak, 1); off += snprint_hex(dst + off, size - off, &pnai->btSak, 1);
if (verbose) { if (verbose) {
if (nai.btSak & SAK_UID_NOT_COMPLETE) { if (pnai->btSak & SAK_UID_NOT_COMPLETE) {
dst += sprintf(dst, "* Warning! Cascade bit set: UID not complete\n"); off += snprintf(dst + off, size - off, "* Warning! Cascade bit set: UID not complete\n");
} }
if (nai.btSak & SAK_ISO14443_4_COMPLIANT) { if (pnai->btSak & SAK_ISO14443_4_COMPLIANT) {
dst += sprintf(dst, "* Compliant with ISO/IEC 14443-4\n"); off += snprintf(dst + off, size - off, "* Compliant with ISO/IEC 14443-4\n");
} else { } else {
dst += sprintf(dst, "* Not compliant with ISO/IEC 14443-4\n"); off += snprintf(dst + off, size - off, "* Not compliant with ISO/IEC 14443-4\n");
} }
if (nai.btSak & SAK_ISO18092_COMPLIANT) { if (pnai->btSak & SAK_ISO18092_COMPLIANT) {
dst += sprintf(dst, "* Compliant with ISO/IEC 18092\n"); off += snprintf(dst + off, size - off, "* Compliant with ISO/IEC 18092\n");
} else { } else {
dst += sprintf(dst, "* Not compliant with ISO/IEC 18092\n"); off += snprintf(dst + off, size - off, "* Not compliant with ISO/IEC 18092\n");
} }
} }
if (nai.szAtsLen) { if (pnai->szAtsLen) {
dst += sprintf(dst, " ATS: "); off += snprintf(dst + off, size - off, " ATS: ");
dst += sprint_hex(dst, nai.abtAts, nai.szAtsLen); off += snprint_hex(dst + off, size - off, pnai->abtAts, pnai->szAtsLen);
} }
if (nai.szAtsLen && verbose) { if (pnai->szAtsLen && verbose) {
// Decode ATS according to ISO/IEC 14443-4 (5.2 Answer to select) // Decode ATS according to ISO/IEC 14443-4 (5.2 Answer to select)
const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 }; const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
dst += sprintf(dst, "* Max Frame Size accepted by PICC: %d bytes\n", iMaxFrameSizes[nai.abtAts[0] & 0x0F]); off += snprintf(dst + off, size - off, "* Max Frame Size accepted by PICC: %d bytes\n", iMaxFrameSizes[pnai->abtAts[0] & 0x0F]);
size_t offset = 1; size_t offset = 1;
if (nai.abtAts[0] & 0x10) { // TA(1) present if (pnai->abtAts[0] & 0x10) { // TA(1) present
uint8_t TA = nai.abtAts[offset]; uint8_t TA = pnai->abtAts[offset];
offset++; offset++;
dst += sprintf(dst, "* Bit Rate Capability:\n"); off += snprintf(dst + off, size - off, "* Bit Rate Capability:\n");
if (TA == 0) { if (TA == 0) {
dst += sprintf(dst, " * PICC supports only 106 kbits/s in both directions\n"); off += snprintf(dst + off, size - off, " * PICC supports only 106 kbits/s in both directions\n");
} }
if (TA & 1 << 7) { if (TA & 1 << 7) {
dst += sprintf(dst, " * Same bitrate in both directions mandatory\n"); off += snprintf(dst + off, size - off, " * Same bitrate in both directions mandatory\n");
} }
if (TA & 1 << 4) { if (TA & 1 << 4) {
dst += sprintf(dst, " * PICC to PCD, DS=2, bitrate 212 kbits/s supported\n"); off += snprintf(dst + off, size - off, " * PICC to PCD, DS=2, bitrate 212 kbits/s supported\n");
} }
if (TA & 1 << 5) { if (TA & 1 << 5) {
dst += sprintf(dst, " * PICC to PCD, DS=4, bitrate 424 kbits/s supported\n"); off += snprintf(dst + off, size - off, " * PICC to PCD, DS=4, bitrate 424 kbits/s supported\n");
} }
if (TA & 1 << 6) { if (TA & 1 << 6) {
dst += sprintf(dst, " * PICC to PCD, DS=8, bitrate 847 kbits/s supported\n"); off += snprintf(dst + off, size - off, " * PICC to PCD, DS=8, bitrate 847 kbits/s supported\n");
} }
if (TA & 1 << 0) { if (TA & 1 << 0) {
dst += sprintf(dst, " * PCD to PICC, DR=2, bitrate 212 kbits/s supported\n"); off += snprintf(dst + off, size - off, " * PCD to PICC, DR=2, bitrate 212 kbits/s supported\n");
} }
if (TA & 1 << 1) { if (TA & 1 << 1) {
dst += sprintf(dst, " * PCD to PICC, DR=4, bitrate 424 kbits/s supported\n"); off += snprintf(dst + off, size - off, " * PCD to PICC, DR=4, bitrate 424 kbits/s supported\n");
} }
if (TA & 1 << 2) { if (TA & 1 << 2) {
dst += sprintf(dst, " * PCD to PICC, DR=8, bitrate 847 kbits/s supported\n"); off += snprintf(dst + off, size - off, " * PCD to PICC, DR=8, bitrate 847 kbits/s supported\n");
} }
if (TA & 1 << 3) { if (TA & 1 << 3) {
dst += sprintf(dst, " * ERROR unknown value\n"); off += snprintf(dst + off, size - off, " * ERROR unknown value\n");
} }
} }
if (nai.abtAts[0] & 0x20) { // TB(1) present if (pnai->abtAts[0] & 0x20) { // TB(1) present
uint8_t TB = nai.abtAts[offset]; uint8_t TB = pnai->abtAts[offset];
offset++; offset++;
dst += sprintf(dst, "* Frame Waiting Time: %.4g ms\n", 256.0 * 16.0 * (1 << ((TB & 0xf0) >> 4)) / 13560.0); off += snprintf(dst + off, size - off, "* Frame Waiting Time: %.4g ms\n", 256.0 * 16.0 * (1 << ((TB & 0xf0) >> 4)) / 13560.0);
if ((TB & 0x0f) == 0) { if ((TB & 0x0f) == 0) {
dst += sprintf(dst, "* No Start-up Frame Guard Time required\n"); off += snprintf(dst + off, size - off, "* No Start-up Frame Guard Time required\n");
} else { } else {
dst += sprintf(dst, "* Start-up Frame Guard Time: %.4g ms\n", 256.0 * 16.0 * (1 << (TB & 0x0f)) / 13560.0); off += snprintf(dst + off, size - off, "* Start-up Frame Guard Time: %.4g ms\n", 256.0 * 16.0 * (1 << (TB & 0x0f)) / 13560.0);
} }
} }
if (nai.abtAts[0] & 0x40) { // TC(1) present if (pnai->abtAts[0] & 0x40) { // TC(1) present
uint8_t TC = nai.abtAts[offset]; uint8_t TC = pnai->abtAts[offset];
offset++; offset++;
if (TC & 0x1) { if (TC & 0x1) {
dst += sprintf(dst, "* Node ADdress supported\n"); off += snprintf(dst + off, size - off, "* Node Address supported\n");
} else { } else {
dst += sprintf(dst, "* Node ADdress not supported\n"); off += snprintf(dst + off, size - off, "* Node Address not supported\n");
} }
if (TC & 0x2) { if (TC & 0x2) {
dst += sprintf(dst, "* Card IDentifier supported\n"); off += snprintf(dst + off, size - off, "* Card IDentifier supported\n");
} else { } else {
dst += sprintf(dst, "* Card IDentifier not supported\n"); off += snprintf(dst + off, size - off, "* Card IDentifier not supported\n");
} }
} }
if (nai.szAtsLen > offset) { if (pnai->szAtsLen > offset) {
dst += sprintf(dst, "* Historical bytes Tk: "); off += snprintf(dst + off, size - off, "* Historical bytes Tk: ");
dst += sprint_hex(dst, nai.abtAts + offset, (nai.szAtsLen - offset)); off += snprint_hex(dst + off, size - off, pnai->abtAts + offset, (pnai->szAtsLen - offset));
uint8_t CIB = nai.abtAts[offset]; uint8_t CIB = pnai->abtAts[offset];
offset++; offset++;
if (CIB != 0x00 && CIB != 0x10 && (CIB & 0xf0) != 0x80) { if (CIB != 0x00 && CIB != 0x10 && (CIB & 0xf0) != 0x80) {
dst += sprintf(dst, " * Proprietary format\n"); off += snprintf(dst + off, size - off, " * Proprietary format\n");
if (CIB == 0xc1) { if (CIB == 0xc1) {
dst += sprintf(dst, " * Tag byte: Mifare or virtual cards of various types\n"); off += snprintf(dst + off, size - off, " * Tag byte: Mifare or virtual cards of various types\n");
uint8_t L = nai.abtAts[offset]; uint8_t L = pnai->abtAts[offset];
offset++; offset++;
if (L != (nai.szAtsLen - offset)) { if (L != (pnai->szAtsLen - offset)) {
dst += sprintf(dst, " * Warning: Type Identification Coding length (%i)", L); off += snprintf(dst + off, size - off, " * Warning: Type Identification Coding length (%i)", L);
dst += sprintf(dst, " not matching Tk length (%zi)\n", (nai.szAtsLen - offset)); off += snprintf(dst + off, size - off, " not matching Tk length (%" PRIdPTR ")\n", (pnai->szAtsLen - offset));
} }
if ((nai.szAtsLen - offset - 2) > 0) { // Omit 2 CRC bytes if ((pnai->szAtsLen - offset - 2) > 0) { // Omit 2 CRC bytes
uint8_t CTC = nai.abtAts[offset]; uint8_t CTC = pnai->abtAts[offset];
offset++; offset++;
dst += sprintf(dst, " * Chip Type: "); off += snprintf(dst + off, size - off, " * Chip Type: ");
switch (CTC & 0xf0) { switch (CTC & 0xf0) {
case 0x00: case 0x00:
dst += sprintf(dst, "(Multiple) Virtual Cards\n"); off += snprintf(dst + off, size - off, "(Multiple) Virtual Cards\n");
break; break;
case 0x10: case 0x10:
dst += sprintf(dst, "Mifare DESFire\n"); off += snprintf(dst + off, size - off, "Mifare DESFire\n");
break; break;
case 0x20: case 0x20:
dst += sprintf(dst, "Mifare Plus\n"); off += snprintf(dst + off, size - off, "Mifare Plus\n");
break; break;
default: default:
dst += sprintf(dst, "RFU\n"); off += snprintf(dst + off, size - off, "RFU\n");
break; break;
} }
dst += sprintf(dst, " * Memory size: "); off += snprintf(dst + off, size - off, " * Memory size: ");
switch (CTC & 0x0f) { switch (CTC & 0x0f) {
case 0x00: case 0x00:
dst += sprintf(dst, "<1 kbyte\n"); off += snprintf(dst + off, size - off, "<1 kbyte\n");
break; break;
case 0x01: case 0x01:
dst += sprintf(dst, "1 kbyte\n"); off += snprintf(dst + off, size - off, "1 kbyte\n");
break; break;
case 0x02: case 0x02:
dst += sprintf(dst, "2 kbyte\n"); off += snprintf(dst + off, size - off, "2 kbyte\n");
break; break;
case 0x03: case 0x03:
dst += sprintf(dst, "4 kbyte\n"); off += snprintf(dst + off, size - off, "4 kbyte\n");
break; break;
case 0x04: case 0x04:
dst += sprintf(dst, "8 kbyte\n"); off += snprintf(dst + off, size - off, "8 kbyte\n");
break; break;
case 0x0f: case 0x0f:
dst += sprintf(dst, "Unspecified\n"); off += snprintf(dst + off, size - off, "Unspecified\n");
break; break;
default: default:
dst += sprintf(dst, "RFU\n"); off += snprintf(dst + off, size - off, "RFU\n");
break; break;
} }
} }
if ((nai.szAtsLen - offset) > 0) { // Omit 2 CRC bytes if ((pnai->szAtsLen - offset) > 0) { // Omit 2 CRC bytes
uint8_t CVC = nai.abtAts[offset]; uint8_t CVC = pnai->abtAts[offset];
offset++; offset++;
dst += sprintf(dst, " * Chip Status: "); off += snprintf(dst + off, size - off, " * Chip Status: ");
switch (CVC & 0xf0) { switch (CVC & 0xf0) {
case 0x00: case 0x00:
dst += sprintf(dst, "Engineering sample\n"); off += snprintf(dst + off, size - off, "Engineering sample\n");
break; break;
case 0x20: case 0x20:
dst += sprintf(dst, "Released\n"); off += snprintf(dst + off, size - off, "Released\n");
break; break;
default: default:
dst += sprintf(dst, "RFU\n"); off += snprintf(dst + off, size - off, "RFU\n");
break; break;
} }
dst += sprintf(dst, " * Chip Generation: "); off += snprintf(dst + off, size - off, " * Chip Generation: ");
switch (CVC & 0x0f) { switch (CVC & 0x0f) {
case 0x00: case 0x00:
dst += sprintf(dst, "Generation 1\n"); off += snprintf(dst + off, size - off, "Generation 1\n");
break; break;
case 0x01: case 0x01:
dst += sprintf(dst, "Generation 2\n"); off += snprintf(dst + off, size - off, "Generation 2\n");
break; break;
case 0x02: case 0x02:
dst += sprintf(dst, "Generation 3\n"); off += snprintf(dst + off, size - off, "Generation 3\n");
break; break;
case 0x0f: case 0x0f:
dst += sprintf(dst, "Unspecified\n"); off += snprintf(dst + off, size - off, "Unspecified\n");
break; break;
default: default:
dst += sprintf(dst, "RFU\n"); off += snprintf(dst + off, size - off, "RFU\n");
break; break;
} }
} }
if ((nai.szAtsLen - offset) > 0) { // Omit 2 CRC bytes if ((pnai->szAtsLen - offset) > 0) { // Omit 2 CRC bytes
uint8_t VCS = nai.abtAts[offset]; uint8_t VCS = pnai->abtAts[offset];
offset++; offset++;
dst += sprintf(dst, " * Specifics (Virtual Card Selection):\n"); off += snprintf(dst + off, size - off, " * Specifics (Virtual Card Selection):\n");
if ((VCS & 0x09) == 0x00) { if ((VCS & 0x09) == 0x00) {
dst += sprintf(dst, " * Only VCSL supported\n"); off += snprintf(dst + off, size - off, " * Only VCSL supported\n");
} else if ((VCS & 0x09) == 0x01) { } else if ((VCS & 0x09) == 0x01) {
dst += sprintf(dst, " * VCS, VCSL and SVC supported\n"); off += snprintf(dst + off, size - off, " * VCS, VCSL and SVC supported\n");
} }
if ((VCS & 0x0e) == 0x00) { if ((VCS & 0x0e) == 0x00) {
dst += sprintf(dst, " * SL1, SL2(?), SL3 supported\n"); off += snprintf(dst + off, size - off, " * SL1, SL2(?), SL3 supported\n");
} else if ((VCS & 0x0e) == 0x02) { } else if ((VCS & 0x0e) == 0x02) {
dst += sprintf(dst, " * SL3 only card\n"); off += snprintf(dst + off, size - off, " * SL3 only card\n");
} else if ((VCS & 0x0f) == 0x0e) { } else if ((VCS & 0x0f) == 0x0e) {
dst += sprintf(dst, " * No VCS command supported\n"); off += snprintf(dst + off, size - off, " * No VCS command supported\n");
} else if ((VCS & 0x0f) == 0x0f) { } else if ((VCS & 0x0f) == 0x0f) {
dst += sprintf(dst, " * Unspecified\n"); off += snprintf(dst + off, size - off, " * Unspecified\n");
} else { } else {
dst += sprintf(dst, " * RFU\n"); off += snprintf(dst + off, size - off, " * RFU\n");
} }
} }
} }
} else { } else {
if (CIB == 0x00) { if (CIB == 0x00) {
dst += sprintf(dst, " * Tk after 0x00 consist of optional consecutive COMPACT-TLV data objects\n"); off += snprintf(dst + off, size - off, " * Tk after 0x00 consist of optional consecutive COMPACT-TLV data objects\n");
dst += sprintf(dst, " followed by a mandatory status indicator (the last three bytes, not in TLV)\n"); off += snprintf(dst + off, size - off, " followed by a mandatory status indicator (the last three bytes, not in TLV)\n");
dst += sprintf(dst, " See ISO/IEC 7816-4 8.1.1.3 for more info\n"); off += snprintf(dst + off, size - off, " See ISO/IEC 7816-4 8.1.1.3 for more info\n");
} }
if (CIB == 0x10) { if (CIB == 0x10) {
dst += sprintf(dst, " * DIR data reference: %02x\n", nai.abtAts[offset]); off += snprintf(dst + off, size - off, " * DIR data reference: %02x\n", pnai->abtAts[offset]);
} }
if (CIB == 0x80) { if (CIB == 0x80) {
if (nai.szAtsLen == offset) { if (pnai->szAtsLen == offset) {
dst += sprintf(dst, " * No COMPACT-TLV objects found, no status found\n"); off += snprintf(dst + off, size - off, " * No COMPACT-TLV objects found, no status found\n");
} else { } else {
dst += sprintf(dst, " * Tk after 0x80 consist of optional consecutive COMPACT-TLV data objects;\n"); off += snprintf(dst + off, size - off, " * Tk after 0x80 consist of optional consecutive COMPACT-TLV data objects;\n");
dst += sprintf(dst, " the last data object may carry a status indicator of one, two or three bytes.\n"); off += snprintf(dst + off, size - off, " the last data object may carry a status indicator of one, two or three bytes.\n");
dst += sprintf(dst, " See ISO/IEC 7816-4 8.1.1.3 for more info\n"); off += snprintf(dst + off, size - off, " See ISO/IEC 7816-4 8.1.1.3 for more info\n");
} }
} }
} }
} }
} }
if (verbose) { if (verbose) {
dst += sprintf(dst, "\nFingerprinting based on MIFARE type Identification Procedure:\n"); // AN10833 off += snprintf(dst + off, size - off, "\nFingerprinting based on MIFARE type Identification Procedure:\n"); // AN10833
uint16_t atqa = 0; uint16_t atqa = 0;
uint8_t sak = 0; uint8_t sak = 0;
uint8_t i, j; uint8_t i, j;
bool found_possible_match = false; bool found_possible_match = false;
atqa = (((uint16_t)nai.abtAtqa[0] & 0xff) << 8); atqa = (((uint16_t)pnai->abtAtqa[0] & 0xff) << 8);
atqa += (((uint16_t)nai.abtAtqa[1] & 0xff)); atqa += (((uint16_t)pnai->abtAtqa[1] & 0xff));
sak = ((uint8_t)nai.btSak & 0xff); sak = ((uint8_t)pnai->btSak & 0xff);
for (i = 0; i < sizeof(const_ca) / sizeof(const_ca[0]); i++) { for (i = 0; i < sizeof(const_ca) / sizeof(const_ca[0]); i++) {
if ((atqa & const_ca[i].mask) == const_ca[i].atqa) { if ((atqa & const_ca[i].mask) == const_ca[i].atqa) {
for (j = 0; (j < sizeof(const_ca[i].saklist)) && (const_ca[i].saklist[j] >= 0); j++) { for (j = 0; (j < sizeof(const_ca[i].saklist)) && (const_ca[i].saklist[j] >= 0); j++) {
int sakindex = const_ca[i].saklist[j]; int sakindex = const_ca[i].saklist[j];
if ((sak & const_cs[sakindex].mask) == const_cs[sakindex].sak) { if ((sak & const_cs[sakindex].mask) == const_cs[sakindex].sak) {
dst += sprintf(dst, "* %s%s\n", const_ca[i].type, const_cs[sakindex].type); off += snprintf(dst + off, size - off, "* %s%s\n", const_ca[i].type, const_cs[sakindex].type);
found_possible_match = true; found_possible_match = true;
} }
} }
@ -418,226 +419,236 @@ sprint_nfc_iso14443a_info(char *dst, const nfc_iso14443a_info nai, bool verbose)
// Other matches not described in // Other matches not described in
// AN10833 MIFARE Type Identification Procedure // AN10833 MIFARE Type Identification Procedure
// but seen in the field: // but seen in the field:
dst += sprintf(dst, "Other possible matches based on ATQA & SAK values:\n"); off += snprintf(dst + off, size - off, "Other possible matches based on ATQA & SAK values:\n");
uint32_t atqasak = 0; uint32_t atqasak = 0;
atqasak += (((uint32_t)nai.abtAtqa[0] & 0xff) << 16); atqasak += (((uint32_t)pnai->abtAtqa[0] & 0xff) << 16);
atqasak += (((uint32_t)nai.abtAtqa[1] & 0xff) << 8); atqasak += (((uint32_t)pnai->abtAtqa[1] & 0xff) << 8);
atqasak += ((uint32_t)nai.btSak & 0xff); atqasak += ((uint32_t)pnai->btSak & 0xff);
switch (atqasak) { switch (atqasak) {
case 0x000488: case 0x000488:
dst += sprintf(dst, "* Mifare Classic 1K Infineon\n"); off += snprintf(dst + off, size - off, "* Mifare Classic 1K Infineon\n");
found_possible_match = true; found_possible_match = true;
break; break;
case 0x000298: case 0x000298:
dst += sprintf(dst, "* Gemplus MPCOS\n"); off += snprintf(dst + off, size - off, "* Gemplus MPCOS\n");
found_possible_match = true; found_possible_match = true;
break; break;
case 0x030428: case 0x030428:
dst += sprintf(dst, "* JCOP31\n"); off += snprintf(dst + off, size - off, "* JCOP31\n");
found_possible_match = true; found_possible_match = true;
break; break;
case 0x004820: case 0x004820:
dst += sprintf(dst, "* JCOP31 v2.4.1\n"); off += snprintf(dst + off, size - off, "* JCOP31 v2.4.1\n");
dst += sprintf(dst, "* JCOP31 v2.2\n"); off += snprintf(dst + off, size - off, "* JCOP31 v2.2\n");
found_possible_match = true; found_possible_match = true;
break; break;
case 0x000428: case 0x000428:
dst += sprintf(dst, "* JCOP31 v2.3.1\n"); off += snprintf(dst + off, size - off, "* JCOP31 v2.3.1\n");
found_possible_match = true; found_possible_match = true;
break; break;
case 0x000453: case 0x000453:
dst += sprintf(dst, "* Fudan FM1208SH01\n"); off += snprintf(dst + off, size - off, "* Fudan FM1208SH01\n");
found_possible_match = true; found_possible_match = true;
break; break;
case 0x000820: case 0x000820:
dst += sprintf(dst, "* Fudan FM1208\n"); off += snprintf(dst + off, size - off, "* Fudan FM1208\n");
found_possible_match = true; found_possible_match = true;
break; break;
case 0x000238: case 0x000238:
dst += sprintf(dst, "* MFC 4K emulated by Nokia 6212 Classic\n"); off += snprintf(dst + off, size - off, "* MFC 4K emulated by Nokia 6212 Classic\n");
found_possible_match = true; found_possible_match = true;
break; break;
case 0x000838: case 0x000838:
dst += sprintf(dst, "* MFC 4K emulated by Nokia 6131 NFC\n"); off += snprintf(dst + off, size - off, "* MFC 4K emulated by Nokia 6131 NFC\n");
found_possible_match = true; found_possible_match = true;
break; break;
} }
if (! found_possible_match) { if (! found_possible_match) {
sprintf(dst, "* Unknown card, sorry\n"); snprintf(dst + off, size - off, "* Unknown card, sorry\n");
} }
} }
} }
void void
sprint_nfc_felica_info(char *dst, const nfc_felica_info nfi, bool verbose) snprint_nfc_felica_info(char *dst, size_t size, const nfc_felica_info *pnfi, bool verbose)
{ {
(void) verbose; (void) verbose;
dst += sprintf(dst, " ID (NFCID2): "); int off = 0;
dst += sprint_hex(dst, nfi.abtId, 8); off += snprintf(dst + off, size - off, " ID (NFCID2): ");
dst += sprintf(dst, " Parameter (PAD): "); off += snprint_hex(dst + off, size - off, pnfi->abtId, 8);
dst += sprint_hex(dst, nfi.abtPad, 8); off += snprintf(dst + off, size - off, " Parameter (PAD): ");
dst += sprintf(dst, " System Code (SC): "); off += snprint_hex(dst + off, size - off, pnfi->abtPad, 8);
sprint_hex(dst, nfi.abtSysCode, 2); off += snprintf(dst + off, size - off, " System Code (SC): ");
snprint_hex(dst + off, size - off, pnfi->abtSysCode, 2);
} }
void void
sprint_nfc_jewel_info(char *dst, const nfc_jewel_info nji, bool verbose) snprint_nfc_jewel_info(char *dst, size_t size, const nfc_jewel_info *pnji, bool verbose)
{ {
(void) verbose; (void) verbose;
dst += sprintf(dst, " ATQA (SENS_RES): "); int off = 0;
dst += sprint_hex(dst, nji.btSensRes, 2); off += snprintf(dst + off, size - off, " ATQA (SENS_RES): ");
dst += sprintf(dst, " 4-LSB JEWELID: "); off += snprint_hex(dst + off, size - off, pnji->btSensRes, 2);
sprint_hex(dst, nji.btId, 4); off += snprintf(dst + off, size - off, " 4-LSB JEWELID: ");
snprint_hex(dst + off, size - off, pnji->btId, 4);
} }
#define PI_ISO14443_4_SUPPORTED 0x01 #define PI_ISO14443_4_SUPPORTED 0x01
#define PI_NAD_SUPPORTED 0x01 #define PI_NAD_SUPPORTED 0x01
#define PI_CID_SUPPORTED 0x02 #define PI_CID_SUPPORTED 0x02
void void
sprint_nfc_iso14443b_info(char *dst, const nfc_iso14443b_info nbi, bool verbose) snprint_nfc_iso14443b_info(char *dst, size_t size, const nfc_iso14443b_info *pnbi, bool verbose)
{ {
const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 }; int off = 0;
dst += sprintf(dst, " PUPI: "); off += snprintf(dst + off, size - off, " PUPI: ");
dst += sprint_hex(dst, nbi.abtPupi, 4); off += snprint_hex(dst + off, size - off, pnbi->abtPupi, 4);
dst += sprintf(dst, " Application Data: "); off += snprintf(dst + off, size - off, " Application Data: ");
dst += sprint_hex(dst, nbi.abtApplicationData, 4); off += snprint_hex(dst + off, size - off, pnbi->abtApplicationData, 4);
dst += sprintf(dst, " Protocol Info: "); off += snprintf(dst + off, size - off, " Protocol Info: ");
dst += sprint_hex(dst, nbi.abtProtocolInfo, 3); off += snprint_hex(dst + off, size - off, pnbi->abtProtocolInfo, 3);
if (verbose) { if (verbose) {
dst += sprintf(dst, "* Bit Rate Capability:\n"); off += snprintf(dst + off, size - off, "* Bit Rate Capability:\n");
if (nbi.abtProtocolInfo[0] == 0) { if (pnbi->abtProtocolInfo[0] == 0) {
dst += sprintf(dst, " * PICC supports only 106 kbits/s in both directions\n"); off += snprintf(dst + off, size - off, " * PICC supports only 106 kbits/s in both directions\n");
} }
if (nbi.abtProtocolInfo[0] & 1 << 7) { if (pnbi->abtProtocolInfo[0] & 1 << 7) {
dst += sprintf(dst, " * Same bitrate in both directions mandatory\n"); off += snprintf(dst + off, size - off, " * Same bitrate in both directions mandatory\n");
} }
if (nbi.abtProtocolInfo[0] & 1 << 4) { if (pnbi->abtProtocolInfo[0] & 1 << 4) {
dst += sprintf(dst, " * PICC to PCD, 1etu=64/fc, bitrate 212 kbits/s supported\n"); off += snprintf(dst + off, size - off, " * PICC to PCD, 1etu=64/fc, bitrate 212 kbits/s supported\n");
} }
if (nbi.abtProtocolInfo[0] & 1 << 5) { if (pnbi->abtProtocolInfo[0] & 1 << 5) {
dst += sprintf(dst, " * PICC to PCD, 1etu=32/fc, bitrate 424 kbits/s supported\n"); off += snprintf(dst + off, size - off, " * PICC to PCD, 1etu=32/fc, bitrate 424 kbits/s supported\n");
} }
if (nbi.abtProtocolInfo[0] & 1 << 6) { if (pnbi->abtProtocolInfo[0] & 1 << 6) {
dst += sprintf(dst, " * PICC to PCD, 1etu=16/fc, bitrate 847 kbits/s supported\n"); off += snprintf(dst + off, size - off, " * PICC to PCD, 1etu=16/fc, bitrate 847 kbits/s supported\n");
} }
if (nbi.abtProtocolInfo[0] & 1 << 0) { if (pnbi->abtProtocolInfo[0] & 1 << 0) {
dst += sprintf(dst, " * PCD to PICC, 1etu=64/fc, bitrate 212 kbits/s supported\n"); off += snprintf(dst + off, size - off, " * PCD to PICC, 1etu=64/fc, bitrate 212 kbits/s supported\n");
} }
if (nbi.abtProtocolInfo[0] & 1 << 1) { if (pnbi->abtProtocolInfo[0] & 1 << 1) {
dst += sprintf(dst, " * PCD to PICC, 1etu=32/fc, bitrate 424 kbits/s supported\n"); off += snprintf(dst + off, size - off, " * PCD to PICC, 1etu=32/fc, bitrate 424 kbits/s supported\n");
} }
if (nbi.abtProtocolInfo[0] & 1 << 2) { if (pnbi->abtProtocolInfo[0] & 1 << 2) {
dst += sprintf(dst, " * PCD to PICC, 1etu=16/fc, bitrate 847 kbits/s supported\n"); off += snprintf(dst + off, size - off, " * PCD to PICC, 1etu=16/fc, bitrate 847 kbits/s supported\n");
} }
if (nbi.abtProtocolInfo[0] & 1 << 3) { if (pnbi->abtProtocolInfo[0] & 1 << 3) {
dst += sprintf(dst, " * ERROR unknown value\n"); off += snprintf(dst + off, size - off, " * ERROR unknown value\n");
} }
if ((nbi.abtProtocolInfo[1] & 0xf0) <= 0x80) { if ((pnbi->abtProtocolInfo[1] & 0xf0) <= 0x80) {
dst += sprintf(dst, "* Maximum frame sizes: %d bytes\n", iMaxFrameSizes[((nbi.abtProtocolInfo[1] & 0xf0) >> 4)]); const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
off += snprintf(dst + off, size - off, "* Maximum frame sizes: %d bytes\n", iMaxFrameSizes[((pnbi->abtProtocolInfo[1] & 0xf0) >> 4)]);
} }
if ((nbi.abtProtocolInfo[1] & 0x0f) == PI_ISO14443_4_SUPPORTED) { if ((pnbi->abtProtocolInfo[1] & 0x0f) == PI_ISO14443_4_SUPPORTED) {
dst += sprintf(dst, "* Protocol types supported: ISO/IEC 14443-4\n"); off += snprintf(dst + off, size - off, "* Protocol types supported: ISO/IEC 14443-4\n");
} }
dst += sprintf(dst, "* Frame Waiting Time: %.4g ms\n", 256.0 * 16.0 * (1 << ((nbi.abtProtocolInfo[2] & 0xf0) >> 4)) / 13560.0); off += snprintf(dst + off, size - off, "* Frame Waiting Time: %.4g ms\n", 256.0 * 16.0 * (1 << ((pnbi->abtProtocolInfo[2] & 0xf0) >> 4)) / 13560.0);
if ((nbi.abtProtocolInfo[2] & (PI_NAD_SUPPORTED | PI_CID_SUPPORTED)) != 0) { if ((pnbi->abtProtocolInfo[2] & (PI_NAD_SUPPORTED | PI_CID_SUPPORTED)) != 0) {
dst += sprintf(dst, "* Frame options supported: "); off += snprintf(dst + off, size - off, "* Frame options supported: ");
if ((nbi.abtProtocolInfo[2] & PI_NAD_SUPPORTED) != 0) dst += sprintf(dst, "NAD "); if ((pnbi->abtProtocolInfo[2] & PI_NAD_SUPPORTED) != 0) off += snprintf(dst + off, size - off, "NAD ");
if ((nbi.abtProtocolInfo[2] & PI_CID_SUPPORTED) != 0) dst += sprintf(dst, "CID "); if ((pnbi->abtProtocolInfo[2] & PI_CID_SUPPORTED) != 0) off += snprintf(dst + off, size - off, "CID ");
sprintf(dst, "\n"); snprintf(dst + off, size - off, "\n");
} }
} }
} }
void void
sprint_nfc_iso14443bi_info(char *dst, const nfc_iso14443bi_info nii, bool verbose) snprint_nfc_iso14443bi_info(char *dst, size_t size, const nfc_iso14443bi_info *pnii, bool verbose)
{ {
dst += sprintf(dst, " DIV: "); int off = 0;
dst += sprint_hex(dst, nii.abtDIV, 4); off += snprintf(dst + off, size - off, " DIV: ");
off += snprint_hex(dst + off, size - off, pnii->abtDIV, 4);
if (verbose) { if (verbose) {
int version = (nii.btVerLog & 0x1e) >> 1; int version = (pnii->btVerLog & 0x1e) >> 1;
dst += sprintf(dst, " Software Version: "); off += snprintf(dst + off, size - off, " Software Version: ");
if (version == 15) { if (version == 15) {
dst += sprintf(dst, "Undefined\n"); off += snprintf(dst + off, size - off, "Undefined\n");
} else { } else {
dst += sprintf(dst, "%i\n", version); off += snprintf(dst + off, size - off, "%i\n", version);
} }
if ((nii.btVerLog & 0x80) && (nii.btConfig & 0x80)) { if ((pnii->btVerLog & 0x80) && (pnii->btConfig & 0x80)) {
dst += sprintf(dst, " Wait Enable: yes"); off += snprintf(dst + off, size - off, " Wait Enable: yes");
} }
} }
if ((nii.btVerLog & 0x80) && (nii.btConfig & 0x40)) { if ((pnii->btVerLog & 0x80) && (pnii->btConfig & 0x40)) {
dst += sprintf(dst, " ATS: "); off += snprintf(dst + off, size - off, " ATS: ");
sprint_hex(dst, nii.abtAtr, nii.szAtrLen); snprint_hex(dst + off, size - off, pnii->abtAtr, pnii->szAtrLen);
} }
} }
void void
sprint_nfc_iso14443b2sr_info(char *dst, const nfc_iso14443b2sr_info nsi, bool verbose) snprint_nfc_iso14443b2sr_info(char *dst, size_t size, const nfc_iso14443b2sr_info *pnsi, bool verbose)
{ {
(void) verbose; (void) verbose;
dst += sprintf(dst, " UID: "); int off = 0;
sprint_hex(dst, nsi.abtUID, 8); off += snprintf(dst + off, size - off, " UID: ");
snprint_hex(dst + off, size - off, pnsi->abtUID, 8);
} }
void void
sprint_nfc_iso14443b2ct_info(char *dst, const nfc_iso14443b2ct_info nci, bool verbose) snprint_nfc_iso14443b2ct_info(char *dst, size_t size, const nfc_iso14443b2ct_info *pnci, bool verbose)
{ {
(void) verbose; (void) verbose;
int off = 0;
uint32_t uid; uint32_t uid;
uid = (nci.abtUID[3] << 24) + (nci.abtUID[2] << 16) + (nci.abtUID[1] << 8) + nci.abtUID[0]; uid = (pnci->abtUID[3] << 24) + (pnci->abtUID[2] << 16) + (pnci->abtUID[1] << 8) + pnci->abtUID[0];
dst += sprintf(dst, " UID: "); off += snprintf(dst + off, size - off, " UID: ");
dst += sprint_hex(dst, nci.abtUID, sizeof(nci.abtUID)); off += snprint_hex(dst + off, size - off, pnci->abtUID, sizeof(pnci->abtUID));
dst += sprintf(dst, " UID (decimal): %010u\n", uid); off += snprintf(dst + off, size - off, " UID (decimal): %010u\n", uid);
dst += sprintf(dst, " Product Code: %02X\n", nci.btProdCode); off += snprintf(dst + off, size - off, " Product Code: %02X\n", pnci->btProdCode);
sprintf(dst, " Fab Code: %02X\n", nci.btFabCode); snprintf(dst + off, size - off, " Fab Code: %02X\n", pnci->btFabCode);
} }
void void
sprint_nfc_dep_info(char *dst, const nfc_dep_info ndi, bool verbose) snprint_nfc_dep_info(char *dst, size_t size, const nfc_dep_info *pndi, bool verbose)
{ {
(void) verbose; (void) verbose;
dst += sprintf(dst, " NFCID3: "); int off = 0;
dst += sprint_hex(dst, ndi.abtNFCID3, 10); off += snprintf(dst + off, size - off, " NFCID3: ");
dst += sprintf(dst, " BS: %02x\n", ndi.btBS); off += snprint_hex(dst + off, size - off, pndi->abtNFCID3, 10);
dst += sprintf(dst, " BR: %02x\n", ndi.btBR); off += snprintf(dst + off, size - off, " BS: %02x\n", pndi->btBS);
dst += sprintf(dst, " TO: %02x\n", ndi.btTO); off += snprintf(dst + off, size - off, " BR: %02x\n", pndi->btBR);
dst += sprintf(dst, " PP: %02x\n", ndi.btPP); off += snprintf(dst + off, size - off, " TO: %02x\n", pndi->btTO);
if (ndi.szGB) { off += snprintf(dst + off, size - off, " PP: %02x\n", pndi->btPP);
dst += sprintf(dst, "General Bytes: "); if (pndi->szGB) {
sprint_hex(dst, ndi.abtGB, ndi.szGB); off += snprintf(dst + off, size - off, "General Bytes: ");
snprint_hex(dst + off, size - off, pndi->abtGB, pndi->szGB);
} }
} }
void void
sprint_nfc_target(char *dst, const nfc_target nt, bool verbose) snprint_nfc_target(char *dst, size_t size, const nfc_target *pnt, bool verbose)
{ {
dst += sprintf(dst, "%s (%s%s) target:\n", str_nfc_modulation_type(nt.nm.nmt), str_nfc_baud_rate(nt.nm.nbr), (nt.nm.nmt != NMT_DEP) ? "" : (nt.nti.ndi.ndm == NDM_ACTIVE) ? "active mode" : "passive mode"); if (NULL != pnt) {
switch (nt.nm.nmt) { int off = 0;
case NMT_ISO14443A: off += snprintf(dst + off, size - off, "%s (%s%s) target:\n", str_nfc_modulation_type(pnt->nm.nmt), str_nfc_baud_rate(pnt->nm.nbr), (pnt->nm.nmt != NMT_DEP) ? "" : (pnt->nti.ndi.ndm == NDM_ACTIVE) ? "active mode" : "passive mode");
sprint_nfc_iso14443a_info(dst, nt.nti.nai, verbose); switch (pnt->nm.nmt) {
break; case NMT_ISO14443A:
case NMT_JEWEL: snprint_nfc_iso14443a_info(dst + off, size - off, &pnt->nti.nai, verbose);
sprint_nfc_jewel_info(dst, nt.nti.nji, verbose); break;
break; case NMT_JEWEL:
case NMT_FELICA: snprint_nfc_jewel_info(dst + off, size - off, &pnt->nti.nji, verbose);
sprint_nfc_felica_info(dst, nt.nti.nfi, verbose); break;
break; case NMT_FELICA:
case NMT_ISO14443B: snprint_nfc_felica_info(dst + off, size - off, &pnt->nti.nfi, verbose);
sprint_nfc_iso14443b_info(dst, nt.nti.nbi, verbose); break;
break; case NMT_ISO14443B:
case NMT_ISO14443BI: snprint_nfc_iso14443b_info(dst + off, size - off, &pnt->nti.nbi, verbose);
sprint_nfc_iso14443bi_info(dst, nt.nti.nii, verbose); break;
break; case NMT_ISO14443BI:
case NMT_ISO14443B2SR: snprint_nfc_iso14443bi_info(dst + off, size - off, &pnt->nti.nii, verbose);
sprint_nfc_iso14443b2sr_info(dst, nt.nti.nsi, verbose); break;
break; case NMT_ISO14443B2SR:
case NMT_ISO14443B2CT: snprint_nfc_iso14443b2sr_info(dst + off, size - off, &pnt->nti.nsi, verbose);
sprint_nfc_iso14443b2ct_info(dst, nt.nti.nci, verbose); break;
break; case NMT_ISO14443B2CT:
case NMT_DEP: snprint_nfc_iso14443b2ct_info(dst + off, size - off, &pnt->nti.nci, verbose);
sprint_nfc_dep_info(dst, nt.nti.ndi, verbose); break;
break; case NMT_DEP:
snprint_nfc_dep_info(dst + off, size - off, &pnt->nti.ndi, verbose);
break;
}
} }
} }

View file

@ -27,15 +27,15 @@
#ifndef _TARGET_SUBR_H_ #ifndef _TARGET_SUBR_H_
#define _TARGET_SUBR_H_ #define _TARGET_SUBR_H_
int sprint_hex(char *dst, const uint8_t *pbtData, const size_t szLen); int snprint_hex(char *dst, size_t size, const uint8_t *pbtData, const size_t szLen);
void sprint_nfc_iso14443a_info(char *dst, const nfc_iso14443a_info nai, bool verbose); void snprint_nfc_iso14443a_info(char *dst, size_t size, const nfc_iso14443a_info *pnai, bool verbose);
void sprint_nfc_iso14443b_info(char *dst, const nfc_iso14443b_info nbi, bool verbose); void snprint_nfc_iso14443b_info(char *dst, size_t size, const nfc_iso14443b_info *pnbi, bool verbose);
void sprint_nfc_iso14443bi_info(char *dst, const nfc_iso14443bi_info nii, bool verbose); void snprint_nfc_iso14443bi_info(char *dst, size_t size, const nfc_iso14443bi_info *pnii, bool verbose);
void sprint_nfc_iso14443b2sr_info(char *dst, const nfc_iso14443b2sr_info nsi, bool verbose); void snprint_nfc_iso14443b2sr_info(char *dst, size_t size, const nfc_iso14443b2sr_info *pnsi, bool verbose);
void sprint_nfc_iso14443b2ct_info(char *dst, const nfc_iso14443b2ct_info nci, bool verbose); void snprint_nfc_iso14443b2ct_info(char *dst, size_t size, const nfc_iso14443b2ct_info *pnci, bool verbose);
void sprint_nfc_felica_info(char *dst, const nfc_felica_info nfi, bool verbose); void snprint_nfc_felica_info(char *dst, size_t size, const nfc_felica_info *pnfi, bool verbose);
void sprint_nfc_jewel_info(char *dst, const nfc_jewel_info nji, bool verbose); void snprint_nfc_jewel_info(char *dst, size_t size, const nfc_jewel_info *pnji, bool verbose);
void sprint_nfc_dep_info(char *dst, const nfc_dep_info ndi, bool verbose); void snprint_nfc_dep_info(char *dst, size_t size, const nfc_dep_info *pndi, bool verbose);
void sprint_nfc_target(char *dst, const nfc_target nt, bool verbose); void snprint_nfc_target(char *dst, size_t size, const nfc_target *pnt, bool verbose);
#endif #endif

View file

@ -105,7 +105,6 @@ target_thread(void *arg)
// Second pass // Second pass
res = nfc_target_receive_bytes(device, abtRx, sizeof(abtRx), 500); res = nfc_target_receive_bytes(device, abtRx, sizeof(abtRx), 500);
cut_assert_operator_int(res, > , 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device))); cut_assert_operator_int(res, > , 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
szRx = (size_t) res;
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data")); cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
if (res <= 0) { thread_res = -1; return (void *) thread_res; } if (res <= 0) { thread_res = -1; return (void *) thread_res; }
@ -117,7 +116,6 @@ target_thread(void *arg)
// Third pass // Third pass
res = nfc_target_receive_bytes(device, abtRx, sizeof(abtRx), 500); res = nfc_target_receive_bytes(device, abtRx, sizeof(abtRx), 500);
cut_assert_operator_int(res, > , 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device))); cut_assert_operator_int(res, > , 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
szRx = (size_t) res;
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data")); cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
if (res <= 0) { thread_res = -1; return (void *) thread_res; } if (res <= 0) { thread_res = -1; return (void *) thread_res; }
@ -129,7 +127,6 @@ target_thread(void *arg)
// Fourth pass // Fourth pass
res = nfc_target_receive_bytes(device, abtRx, sizeof(abtRx), 500); res = nfc_target_receive_bytes(device, abtRx, sizeof(abtRx), 500);
cut_assert_operator_int(res, > , 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device))); cut_assert_operator_int(res, > , 0, cut_message("Can't receive bytes from initiator: %s", nfc_strerror(device)));
szRx = (size_t) res;
cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data")); cut_assert_equal_memory(abtAttRx, sizeof(abtAttRx), abtRx, res, cut_message("Invalid received data"));
if (res <= 0) { thread_res = -1; return (void *) thread_res; } if (res <= 0) { thread_res = -1; return (void *) thread_res; }

View file

@ -71,6 +71,7 @@
#include "nfc-utils.h" #include "nfc-utils.h"
static nfc_device *pnd; static nfc_device *pnd;
static nfc_context *context;
static bool quiet_output = false; static bool quiet_output = false;
// Version of the emulated type4 tag: // Version of the emulated type4 tag:
static int type4v = 2; static int type4v = 2;
@ -237,22 +238,27 @@ nfcforum_tag4_io(struct nfc_emulator *emulator, const uint8_t *data_in, const si
static void stop_emulation(int sig) static void stop_emulation(int sig)
{ {
(void) sig; (void) sig;
if (pnd) if (pnd != NULL) {
nfc_abort_command(pnd); nfc_abort_command(pnd);
else } else {
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
} }
static size_t static int
ndef_message_load(char *filename, struct nfcforum_tag4_ndef_data *tag_data) ndef_message_load(char *filename, struct nfcforum_tag4_ndef_data *tag_data)
{ {
struct stat sb; struct stat sb;
if (stat(filename, &sb) < 0) if (stat(filename, &sb) < 0) {
return 0; printf("file not found or not accessible '%s'", filename);
return -1;
}
/* Check file size */ /* Check file size */
if (sb.st_size > 0xFFFF) { if (sb.st_size > 0xFFFF) {
errx(EXIT_FAILURE, "file size too large '%s'", filename); printf("file size too large '%s'", filename);
return -1;
} }
tag_data->ndef_file_len = sb.st_size + 2; tag_data->ndef_file_len = sb.st_size + 2;
@ -261,29 +267,37 @@ ndef_message_load(char *filename, struct nfcforum_tag4_ndef_data *tag_data)
tag_data->ndef_file[1] = (uint8_t)(sb.st_size); tag_data->ndef_file[1] = (uint8_t)(sb.st_size);
FILE *F; FILE *F;
if (!(F = fopen(filename, "r"))) if (!(F = fopen(filename, "r"))) {
err(EXIT_FAILURE, "fopen (%s, \"r\")", filename); printf("fopen (%s, \"r\")", filename);
return -1;
}
if (1 != fread(tag_data->ndef_file + 2, sb.st_size, 1, F)) if (1 != fread(tag_data->ndef_file + 2, sb.st_size, 1, F)) {
err(EXIT_FAILURE, "Can't read from %s", filename); printf("Can't read from %s", filename);
fclose(F);
return -1;
}
fclose(F); fclose(F);
return sb.st_size; return sb.st_size;
} }
static size_t static int
ndef_message_save(char *filename, struct nfcforum_tag4_ndef_data *tag_data) ndef_message_save(char *filename, struct nfcforum_tag4_ndef_data *tag_data)
{ {
FILE *F; FILE *F;
if (!(F = fopen(filename, "w"))) if (!(F = fopen(filename, "w"))) {
err(EXIT_FAILURE, "fopen (%s, w)", filename); printf("fopen (%s, w)", filename);
return -1;
}
if (1 != fwrite(tag_data->ndef_file + 2, tag_data->ndef_file_len - 2, 1, F)) { if (1 != fwrite(tag_data->ndef_file + 2, tag_data->ndef_file_len - 2, 1, F)) {
err(EXIT_FAILURE, "fwrite (%d)", (int) tag_data->ndef_file_len - 2); printf("fwrite (%d)", (int) tag_data->ndef_file_len - 2);
fclose(F);
return -1;
} }
fclose(F); fclose(F);
return tag_data->ndef_file_len - 2; return tag_data->ndef_file_len - 2;
} }
@ -361,19 +375,24 @@ main(int argc, char *argv[])
// If some file is provided load it // If some file is provided load it
if (argc >= (2 + options)) { if (argc >= (2 + options)) {
if (!ndef_message_load(argv[1 + options], &nfcforum_tag4_data)) { if (ndef_message_load(argv[1 + options], &nfcforum_tag4_data) < 0) {
err(EXIT_FAILURE, "Can't load NDEF file '%s'", argv[1 + options]); printf("Can't load NDEF file '%s'", argv[1 + options]);
exit(EXIT_FAILURE);
} }
} }
nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)\n");
exit(EXIT_FAILURE);
}
// Try to open the NFC reader // Try to open the NFC reader
pnd = nfc_open(context, NULL); pnd = nfc_open(context, NULL);
if (pnd == NULL) { if (pnd == NULL) {
ERR("Unable to open NFC device"); ERR("Unable to open NFC device");
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -384,16 +403,21 @@ main(int argc, char *argv[])
if (0 != nfc_emulate_target(pnd, &emulator, 0)) { // contains already nfc_target_init() call if (0 != nfc_emulate_target(pnd, &emulator, 0)) { // contains already nfc_target_init() call
nfc_perror(pnd, "nfc_emulate_target"); nfc_perror(pnd, "nfc_emulate_target");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
nfc_close(pnd);
if (argc == (3 + options)) { if (argc == (3 + options)) {
if (!(ndef_message_save(argv[2 + options], &nfcforum_tag4_data))) { if (ndef_message_save(argv[2 + options], &nfcforum_tag4_data) < 0) {
err(EXIT_FAILURE, "Can't save NDEF file '%s'", argv[2 + options]); printf("Can't save NDEF file '%s'", argv[2 + options]);
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
} }
nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }

View file

@ -71,6 +71,10 @@ main(int argc, const char *argv[])
nfc_context *context; nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
// Display libnfc version // Display libnfc version
acLibnfcVersion = nfc_version(); acLibnfcVersion = nfc_version();
@ -122,6 +126,7 @@ main(int argc, const char *argv[])
} }
if (nfc_initiator_init(pnd) < 0) { if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init"); nfc_perror(pnd, "nfc_initiator_init");
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -138,7 +143,7 @@ main(int argc, const char *argv[])
printf("%d ISO14443A passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":"); printf("%d ISO14443A passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
} }
for (n = 0; n < res; n++) { for (n = 0; n < res; n++) {
print_nfc_target(ant[n], verbose); print_nfc_target(&ant[n], verbose);
printf("\n"); printf("\n");
} }
} }
@ -152,7 +157,7 @@ main(int argc, const char *argv[])
printf("%d Felica (212 kbps) passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":"); printf("%d Felica (212 kbps) passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
} }
for (n = 0; n < res; n++) { for (n = 0; n < res; n++) {
print_nfc_target(ant[n], verbose); print_nfc_target(&ant[n], verbose);
printf("\n"); printf("\n");
} }
} }
@ -164,7 +169,7 @@ main(int argc, const char *argv[])
printf("%d Felica (424 kbps) passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":"); printf("%d Felica (424 kbps) passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
} }
for (n = 0; n < res; n++) { for (n = 0; n < res; n++) {
print_nfc_target(ant[n], verbose); print_nfc_target(&ant[n], verbose);
printf("\n"); printf("\n");
} }
} }
@ -178,7 +183,7 @@ main(int argc, const char *argv[])
printf("%d ISO14443B passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":"); printf("%d ISO14443B passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
} }
for (n = 0; n < res; n++) { for (n = 0; n < res; n++) {
print_nfc_target(ant[n], verbose); print_nfc_target(&ant[n], verbose);
printf("\n"); printf("\n");
} }
} }
@ -192,7 +197,7 @@ main(int argc, const char *argv[])
printf("%d ISO14443B' passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":"); printf("%d ISO14443B' passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
} }
for (n = 0; n < res; n++) { for (n = 0; n < res; n++) {
print_nfc_target(ant[n], verbose); print_nfc_target(&ant[n], verbose);
printf("\n"); printf("\n");
} }
} }
@ -206,7 +211,7 @@ main(int argc, const char *argv[])
printf("%d ISO14443B-2 ST SRx passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":"); printf("%d ISO14443B-2 ST SRx passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
} }
for (n = 0; n < res; n++) { for (n = 0; n < res; n++) {
print_nfc_target(ant[n], verbose); print_nfc_target(&ant[n], verbose);
printf("\n"); printf("\n");
} }
} }
@ -220,7 +225,7 @@ main(int argc, const char *argv[])
printf("%d ISO14443B-2 ASK CTx passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":"); printf("%d ISO14443B-2 ASK CTx passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
} }
for (n = 0; n < res; n++) { for (n = 0; n < res; n++) {
print_nfc_target(ant[n], verbose); print_nfc_target(&ant[n], verbose);
printf("\n"); printf("\n");
} }
} }
@ -234,7 +239,7 @@ main(int argc, const char *argv[])
printf("%d Jewel passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":"); printf("%d Jewel passive target(s) found%s\n", res, (res == 0) ? ".\n" : ":");
} }
for (n = 0; n < res; n++) { for (n = 0; n < res; n++) {
print_nfc_target(ant[n], verbose); print_nfc_target(&ant[n], verbose);
printf("\n"); printf("\n");
} }
} }
@ -242,5 +247,5 @@ main(int argc, const char *argv[])
} }
nfc_exit(context); nfc_exit(context);
return EXIT_SUCCESS; exit(EXIT_SUCCESS);
} }

View file

@ -175,7 +175,6 @@ authenticate(uint32_t uiBlock)
{ {
mifare_cmd mc; mifare_cmd mc;
uint32_t uiTrailerBlock; uint32_t uiTrailerBlock;
size_t key_index;
// Set the authentication information (uid) // Set the authentication information (uid)
memcpy(mp.mpa.abtAuthUid, nt.nti.nai.abtUid + nt.nti.nai.szUidLen - 4, 4); memcpy(mp.mpa.abtAuthUid, nt.nti.nai.abtUid + nt.nti.nai.szUidLen - 4, 4);
@ -200,7 +199,7 @@ authenticate(uint32_t uiBlock)
return true; return true;
} else { } else {
// Try to guess the right key // Try to guess the right key
for (key_index = 0; key_index < num_keys; key_index++) { for (size_t key_index = 0; key_index < num_keys; key_index++) {
memcpy(mp.mpa.abtKey, keys + (key_index * 6), 6); memcpy(mp.mpa.abtKey, keys + (key_index * 6), 6);
if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp)) { if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp)) {
if (bUseKeyA) if (bUseKeyA)
@ -224,12 +223,12 @@ unlock_card(void)
// Configure the CRC // Configure the CRC
if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) { if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) {
nfc_perror(pnd, "nfc_configure"); nfc_perror(pnd, "nfc_configure");
exit(EXIT_FAILURE); return false;
} }
// Use raw send/receive methods // Use raw send/receive methods
if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) { if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) {
nfc_perror(pnd, "nfc_configure"); nfc_perror(pnd, "nfc_configure");
exit(EXIT_FAILURE); return false;
} }
iso14443a_crc_append(abtHalt, 2); iso14443a_crc_append(abtHalt, 2);
@ -248,12 +247,12 @@ unlock_card(void)
// Configure the CRC // Configure the CRC
if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true) < 0) { if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror(pnd, "nfc_device_set_property_bool");
exit(EXIT_FAILURE); return false;
} }
// Switch off raw send/receive methods // Switch off raw send/receive methods
if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, true) < 0) { if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, true) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror(pnd, "nfc_device_set_property_bool");
exit(EXIT_FAILURE); return false;
} }
return true; return true;
} }
@ -431,8 +430,6 @@ main(int argc, const char *argv[])
{ {
action_t atAction = ACTION_USAGE; action_t atAction = ACTION_USAGE;
uint8_t *pbtUID; uint8_t *pbtUID;
FILE *pfKeys = NULL;
FILE *pfDump = NULL;
int unlock = 0; int unlock = 0;
if (argc < 2) { if (argc < 2) {
@ -465,134 +462,143 @@ main(int argc, const char *argv[])
bUseKeyFile = (argc > 4); bUseKeyFile = (argc > 4);
} }
switch (atAction) { if (atAction == ACTION_USAGE) {
case ACTION_USAGE: print_usage(argv[0]);
print_usage(argv[0]); exit(EXIT_FAILURE);
}
if (bUseKeyFile) {
FILE *pfKeys = fopen(argv[4], "rb");
if (pfKeys == NULL) {
printf("Could not open keys file: %s\n", argv[4]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
break; }
case ACTION_READ: if (fread(&mtKeys, 1, sizeof(mtKeys), pfKeys) != sizeof(mtKeys)) {
case ACTION_WRITE: printf("Could not read keys file: %s\n", argv[4]);
if (bUseKeyFile) { fclose(pfKeys);
pfKeys = fopen(argv[4], "rb"); exit(EXIT_FAILURE);
if (pfKeys == NULL) { }
printf("Could not open keys file: %s\n", argv[4]); fclose(pfKeys);
exit(EXIT_FAILURE); }
}
if (fread(&mtKeys, 1, sizeof(mtKeys), pfKeys) != sizeof(mtKeys)) {
printf("Could not read keys file: %s\n", argv[4]);
fclose(pfKeys);
exit(EXIT_FAILURE);
}
fclose(pfKeys);
}
if (atAction == ACTION_READ) { if (atAction == ACTION_READ) {
memset(&mtDump, 0x00, sizeof(mtDump)); memset(&mtDump, 0x00, sizeof(mtDump));
} else { } else {
pfDump = fopen(argv[3], "rb"); FILE *pfDump = fopen(argv[3], "rb");
if (pfDump == NULL) { if (pfDump == NULL) {
printf("Could not open dump file: %s\n", argv[3]); printf("Could not open dump file: %s\n", argv[3]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
if (fread(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) { }
printf("Could not read dump file: %s\n", argv[3]);
fclose(pfDump);
exit(EXIT_FAILURE);
}
fclose(pfDump);
}
// printf("Successfully opened required files\n");
nfc_init(&context); if (fread(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) {
printf("Could not read dump file: %s\n", argv[3]);
fclose(pfDump);
exit(EXIT_FAILURE);
}
fclose(pfDump);
}
// printf("Successfully opened required files\n");
// Try to open the NFC reader nfc_init(&context);
pnd = nfc_open(context, NULL); if (context == NULL) {
if (pnd == NULL) { ERR("Unable to init libnfc (malloc)");
printf("Error opening NFC reader\n"); exit(EXIT_FAILURE);
exit(EXIT_FAILURE); }
}
if (nfc_initiator_init(pnd) < 0) { // Try to open the NFC reader
nfc_perror(pnd, "nfc_initiator_init"); pnd = nfc_open(context, NULL);
exit(EXIT_FAILURE); if (pnd == NULL) {
}; ERR("Error opening NFC reader");
nfc_exit(context);
exit(EXIT_FAILURE);
}
// Let the reader only try once to find a tag if (nfc_initiator_init(pnd) < 0) {
if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) { nfc_perror(pnd, "nfc_initiator_init");
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_close(pnd);
exit(EXIT_FAILURE); nfc_exit(context);
} exit(EXIT_FAILURE);
// Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance. };
nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, false);
printf("NFC reader: %s opened\n", nfc_device_get_name(pnd)); // Let the reader only try once to find a tag
if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
}
// Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance.
nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, false);
// Try to find a MIFARE Classic tag printf("NFC reader: %s opened\n", nfc_device_get_name(pnd));
if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
printf("Error: no tag was found\n"); // Try to find a MIFARE Classic tag
if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
printf("Error: no tag was found\n");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
}
// Test if we are dealing with a MIFARE compatible tag
if ((nt.nti.nai.btSak & 0x08) == 0) {
printf("Warning: tag is probably not a MFC!\n");
}
// Get the info from the current tag
pbtUID = nt.nti.nai.abtUid;
if (bUseKeyFile) {
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(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]);
}
}
printf("Found MIFARE Classic card:\n");
print_nfc_target(&nt, false);
// Guessing size
if ((nt.nti.nai.abtAtqa[1] & 0x02) == 0x02)
// 4K
uiBlocks = 0xff;
else if ((nt.nti.nai.btSak & 0x01) == 0x01)
// 320b
uiBlocks = 0x13;
else
// 1K
// TODO: for MFP it is 0x7f (2K) but how to be sure it's a MFP? Try to get RATS?
uiBlocks = 0x3f;
printf("Guessing size: seems to be a %i-byte card\n", (uiBlocks + 1) * 16);
if (atAction == ACTION_READ) {
if (read_card(unlock)) {
printf("Writing data to file: %s ...", argv[3]);
fflush(stdout);
FILE *pfDump = fopen(argv[3], "wb");
if (pfDump == NULL) {
printf("Could not open dump file: %s\n", argv[3]);
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Test if we are dealing with a MIFARE compatible tag if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) {
if ((nt.nti.nai.btSak & 0x08) == 0) { printf("\nCould not write to file: %s\n", argv[3]);
printf("Warning: tag is probably not a MFC!\n"); fclose(pfDump);
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("Done.\n");
fclose(pfDump);
}
} else if (atAction == ACTION_WRITE) {
write_card(unlock);
}
// Get the info from the current tag nfc_close(pnd);
pbtUID = nt.nti.nai.abtUid;
if (bUseKeyFile) {
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(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]);
}
}
printf("Found MIFARE Classic card:\n");
print_nfc_target(nt, false);
// Guessing size
if ((nt.nti.nai.abtAtqa[1] & 0x02) == 0x02)
// 4K
uiBlocks = 0xff;
else if ((nt.nti.nai.btSak & 0x01) == 0x01)
// 320b
uiBlocks = 0x13;
else
// 1K
// TODO: for MFP it is 0x7f (2K) but how to be sure it's a MFP? Try to get RATS?
uiBlocks = 0x3f;
printf("Guessing size: seems to be a %i-byte card\n", (uiBlocks + 1) * 16);
if (atAction == ACTION_READ) {
if (read_card(unlock)) {
printf("Writing data to file: %s ...", argv[3]);
fflush(stdout);
pfDump = fopen(argv[3], "wb");
if (pfDump == NULL) {
printf("Could not open dump file: %s\n", argv[3]);
exit(EXIT_FAILURE);
}
if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) {
printf("\nCould not write to file: %s\n", argv[3]);
exit(EXIT_FAILURE);
}
printf("Done.\n");
fclose(pfDump);
}
} else if (atAction == ACTION_WRITE) {
write_card(unlock);
}
nfc_close(pnd);
break;
};
nfc_exit(context); nfc_exit(context);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }

View file

@ -178,7 +178,7 @@ main(int argc, const char *argv[])
printf("r|w - Perform read from or write to card\n"); printf("r|w - Perform read from or write to card\n");
printf("<dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n"); printf("<dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
printf("\n"); printf("\n");
return 1; exit(EXIT_FAILURE);
} }
DBG("\nChecking arguments and settings\n"); DBG("\nChecking arguments and settings\n");
@ -192,13 +192,13 @@ main(int argc, const char *argv[])
if (pfDump == NULL) { if (pfDump == NULL) {
ERR("Could not open dump file: %s\n", argv[2]); ERR("Could not open dump file: %s\n", argv[2]);
return 1; exit(EXIT_FAILURE);
} }
if (fread(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) { if (fread(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) {
ERR("Could not read from dump file: %s\n", argv[2]); ERR("Could not read from dump file: %s\n", argv[2]);
fclose(pfDump); fclose(pfDump);
return 1; exit(EXIT_FAILURE);
} }
fclose(pfDump); fclose(pfDump);
} }
@ -206,22 +206,31 @@ main(int argc, const char *argv[])
nfc_context *context; nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
// Try to open the NFC device // Try to open the NFC device
pnd = nfc_open(context, NULL); pnd = nfc_open(context, NULL);
if (pnd == NULL) { if (pnd == NULL) {
ERR("Error opening NFC device\n"); ERR("Error opening NFC device");
return 1; nfc_exit(context);
exit(EXIT_FAILURE);
} }
if (nfc_initiator_init(pnd) < 0) { if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init"); nfc_perror(pnd, "nfc_initiator_init");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Let the device only try once to find a tag // Let the device only try once to find a tag
if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) { if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror(pnd, "nfc_device_set_property_bool");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -232,7 +241,7 @@ main(int argc, const char *argv[])
ERR("no tag was found\n"); ERR("no tag was found\n");
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
return EXIT_FAILURE; exit(EXIT_FAILURE);
} }
// Test if we are dealing with a MIFARE compatible tag // Test if we are dealing with a MIFARE compatible tag
@ -240,7 +249,7 @@ main(int argc, const char *argv[])
ERR("tag is not a MIFARE Ultralight card\n"); ERR("tag is not a MIFARE Ultralight card\n");
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
return EXIT_FAILURE; exit(EXIT_FAILURE);
} }
// Get the info from the current tag // Get the info from the current tag
printf("Found MIFARE Ultralight card with UID: "); printf("Found MIFARE Ultralight card with UID: ");
@ -257,11 +266,16 @@ main(int argc, const char *argv[])
pfDump = fopen(argv[2], "wb"); pfDump = fopen(argv[2], "wb");
if (pfDump == NULL) { if (pfDump == NULL) {
printf("Could not open file: %s\n", argv[2]); printf("Could not open file: %s\n", argv[2]);
return EXIT_FAILURE; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) { if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) {
printf("Could not write to file: %s\n", argv[2]); printf("Could not write to file: %s\n", argv[2]);
return EXIT_FAILURE; fclose(pfDump);
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
fclose(pfDump); fclose(pfDump);
printf("Done.\n"); printf("Done.\n");
@ -272,5 +286,5 @@ main(int argc, const char *argv[])
nfc_close(pnd); nfc_close(pnd);
nfc_exit(context); nfc_exit(context);
return EXIT_SUCCESS; exit(EXIT_SUCCESS);
} }

View file

@ -60,6 +60,7 @@
#endif #endif
static nfc_device *pnd; static nfc_device *pnd;
static nfc_context *context;
static void static void
print_usage(char *progname) print_usage(char *progname)
@ -72,10 +73,12 @@ print_usage(char *progname)
static void stop_select(int sig) static void stop_select(int sig)
{ {
(void) sig; (void) sig;
if (pnd) if (pnd != NULL) {
nfc_abort_command(pnd); nfc_abort_command(pnd);
else } else {
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
} }
static void static void
@ -196,13 +199,18 @@ main(int argc, char *argv[])
} }
} }
nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)\n");
exit(EXIT_FAILURE);
}
pnd = nfc_open(context, NULL); pnd = nfc_open(context, NULL);
if (pnd == NULL) { if (pnd == NULL) {
ERR("Unable to open NFC device"); ERR("Unable to open NFC device");
fclose(ndef_stream);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -219,17 +227,21 @@ main(int argc, char *argv[])
if (nfc_initiator_init(pnd) < 0) { if (nfc_initiator_init(pnd) < 0) {
nfc_perror(pnd, "nfc_initiator_init"); nfc_perror(pnd, "nfc_initiator_init");
fclose(ndef_stream);
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
fprintf(message_stream, "Place your NFC Forum Tag Type 3 in the field...\n"); fprintf(message_stream, "Place your NFC Forum Tag Type 3 in the field...\n");
int error = EXIT_SUCCESS;
// Polling payload (SENSF_REQ) must be present (see NFC Digital Protol) // Polling payload (SENSF_REQ) must be present (see NFC Digital Protol)
const uint8_t *pbtSensfReq = (uint8_t *)"\x00\xff\xff\x01\x00"; const uint8_t *pbtSensfReq = (uint8_t *)"\x00\xff\xff\x01\x00";
if (nfc_initiator_select_passive_target(pnd, nm, pbtSensfReq, 5, &nt) <= 0) { if (nfc_initiator_select_passive_target(pnd, nm, pbtSensfReq, 5, &nt) <= 0) {
nfc_perror(pnd, "nfc_initiator_select_passive_target"); nfc_perror(pnd, "nfc_initiator_select_passive_target");
error = EXIT_FAILURE; fclose(ndef_stream);
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
// Check if System Code equals 0x12fc // Check if System Code equals 0x12fc
@ -239,14 +251,18 @@ main(int argc, char *argv[])
const uint8_t *pbtSensfReqNfcForum = (uint8_t *)"\x00\x12\xfc\x01\x00"; const uint8_t *pbtSensfReqNfcForum = (uint8_t *)"\x00\x12\xfc\x01\x00";
if (nfc_initiator_select_passive_target(pnd, nm, pbtSensfReqNfcForum, 5, &nt) <= 0) { if (nfc_initiator_select_passive_target(pnd, nm, pbtSensfReqNfcForum, 5, &nt) <= 0) {
nfc_perror(pnd, "nfc_initiator_select_passive_target"); nfc_perror(pnd, "nfc_initiator_select_passive_target");
error = EXIT_FAILURE; fclose(ndef_stream);
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
// Check again if System Code equals 0x12fc // Check again if System Code equals 0x12fc
if (0 != memcmp(nt.nti.nfi.abtSysCode, abtNfcForumSysCode, 2)) { if (0 != memcmp(nt.nti.nfi.abtSysCode, abtNfcForumSysCode, 2)) {
fprintf(stderr, "Tag is not NFC Forum Tag Type 3 compliant.\n"); fprintf(stderr, "Tag is not NFC Forum Tag Type 3 compliant.\n");
error = EXIT_FAILURE; fclose(ndef_stream);
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
} }
@ -254,18 +270,21 @@ main(int argc, char *argv[])
if ((nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) || (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0)) { 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"); nfc_perror(pnd, "nfc_device_set_property_bool");
error = EXIT_FAILURE; fclose(ndef_stream);
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
uint8_t data[1024]; uint8_t data[1024];
size_t data_len = sizeof(data); size_t data_len = sizeof(data);
int len;
if (0 >= (len = nfc_forum_tag_type3_check(pnd, nt, 0, 1, data, &data_len))) { if (nfc_forum_tag_type3_check(pnd, nt, 0, 1, data, &data_len) <= 0) {
nfc_perror(pnd, "nfc_forum_tag_type3_check"); nfc_perror(pnd, "nfc_forum_tag_type3_check");
error = EXIT_FAILURE; fclose(ndef_stream);
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
const int ndef_major_version = (data[0] & 0xf0) >> 4; const int ndef_major_version = (data[0] & 0xf0) >> 4;
@ -285,14 +304,18 @@ main(int argc, char *argv[])
const uint16_t ndef_checksum = (data[14] << 8) + data[15]; const uint16_t ndef_checksum = (data[14] << 8) + data[15];
if (ndef_calculated_checksum != ndef_checksum) { if (ndef_calculated_checksum != ndef_checksum) {
fprintf(stderr, "NDEF CRC does not match with calculated one\n"); fprintf(stderr, "NDEF CRC does not match with calculated one\n");
error = EXIT_FAILURE; fclose(ndef_stream);
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
if (!ndef_data_len) { if (!ndef_data_len) {
fprintf(stderr, "Empty NFC Forum Tag Type 3\n"); fprintf(stderr, "Empty NFC Forum Tag Type 3\n");
error = EXIT_FAILURE; fclose(ndef_stream);
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
const uint8_t block_max_per_check = data[1]; const uint8_t block_max_per_check = data[1];
@ -303,22 +326,23 @@ main(int argc, char *argv[])
size_t size = sizeof(data) - data_len; size_t size = 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, &size)) { 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, &size)) {
nfc_perror(pnd, "nfc_forum_tag_type3_check"); nfc_perror(pnd, "nfc_forum_tag_type3_check");
error = EXIT_FAILURE; fclose(ndef_stream);
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
data_len += size; data_len += size;
} }
if (fwrite(data, 1, data_len, ndef_stream) != data_len) { if (fwrite(data, 1, data_len, ndef_stream) != data_len) {
fprintf(stderr, "Could not write to file.\n"); fprintf(stderr, "Could not write to file.\n");
error = EXIT_FAILURE; fclose(ndef_stream);
goto error; nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
} }
error:
fclose(ndef_stream); fclose(ndef_stream);
if (pnd) { nfc_close(pnd);
nfc_close(pnd);
}
nfc_exit(context); nfc_exit(context);
exit(error); exit(EXIT_SUCCESS);
} }

View file

@ -42,6 +42,7 @@
# include "config.h" # include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
@ -94,29 +95,29 @@ print_usage(char *argv[])
printf("\t-n N\tAdds a waiting time of N seconds (integer) in the relay to mimic long distance.\n"); printf("\t-n N\tAdds a waiting time of N seconds (integer) in the relay to mimic long distance.\n");
} }
static bool print_hex_fd4(const uint8_t *pbtData, const size_t szBytes, const char *pchPrefix) static int print_hex_fd4(const uint8_t *pbtData, const size_t szBytes, const char *pchPrefix)
{ {
size_t szPos; size_t szPos;
if (szBytes > MAX_FRAME_LEN) { if (szBytes > MAX_FRAME_LEN) {
return EXIT_FAILURE; return -1;
} }
if (fprintf(fd4, "#%s %04zx: ", pchPrefix, szBytes) < 0) { if (fprintf(fd4, "#%s %04" PRIxPTR ": ", pchPrefix, szBytes) < 0) {
return EXIT_FAILURE; return -1;
} }
for (szPos = 0; szPos < szBytes; szPos++) { for (szPos = 0; szPos < szBytes; szPos++) {
if (fprintf(fd4, "%02x ", pbtData[szPos]) < 0) { if (fprintf(fd4, "%02x ", pbtData[szPos]) < 0) {
return EXIT_FAILURE; return -1;
} }
} }
if (fprintf(fd4, "\n") < 0) { if (fprintf(fd4, "\n") < 0) {
return EXIT_FAILURE; return -1;
} }
fflush(fd4); fflush(fd4);
return EXIT_SUCCESS; return 0;
} }
static bool scan_hex_fd3(uint8_t *pbtData, size_t *pszBytes, const char *pchPrefix) static int scan_hex_fd3(uint8_t *pbtData, size_t *pszBytes, const char *pchPrefix)
{ {
size_t szPos; size_t szPos;
unsigned int uiBytes; unsigned int uiBytes;
@ -126,25 +127,26 @@ static bool scan_hex_fd3(uint8_t *pbtData, size_t *pszBytes, const char *pchPref
// Look for our next sync marker // Look for our next sync marker
while ((c = fgetc(fd3)) != '#') { while ((c = fgetc(fd3)) != '#') {
if (c == EOF) { if (c == EOF) {
return EXIT_FAILURE; return -1;
} }
} }
strncpy(pchScan, pchPrefix, 250); strncpy(pchScan, pchPrefix, 250);
pchScan[sizeof(pchScan) - 1] = '\0';
strcat(pchScan, " %04x:"); strcat(pchScan, " %04x:");
if (fscanf(fd3, pchScan, &uiBytes) < 1) { if (fscanf(fd3, pchScan, &uiBytes) < 1) {
return EXIT_FAILURE; return -1;
} }
*pszBytes = uiBytes; *pszBytes = uiBytes;
if (*pszBytes > MAX_FRAME_LEN) { if (*pszBytes > MAX_FRAME_LEN) {
return EXIT_FAILURE; return -1;
} }
for (szPos = 0; szPos < *pszBytes; szPos++) { for (szPos = 0; szPos < *pszBytes; szPos++) {
if (fscanf(fd3, "%02x", &uiData) < 1) { if (fscanf(fd3, "%02x", &uiData) < 1) {
return EXIT_FAILURE; return -1;
} }
pbtData[szPos] = uiData; pbtData[szPos] = uiData;
} }
return EXIT_SUCCESS; return 0;
} }
int int
@ -158,7 +160,7 @@ main(int argc, char *argv[])
for (arg = 1; arg < argc; arg++) { for (arg = 1; arg < argc; arg++) {
if (0 == strcmp(argv[arg], "-h")) { if (0 == strcmp(argv[arg], "-h")) {
print_usage(argv); print_usage(argv);
return EXIT_SUCCESS; exit(EXIT_SUCCESS);
} else if (0 == strcmp(argv[arg], "-q")) { } else if (0 == strcmp(argv[arg], "-q")) {
quiet_output = true; quiet_output = true;
} else if (0 == strcmp(argv[arg], "-t")) { } else if (0 == strcmp(argv[arg], "-t")) {
@ -173,16 +175,16 @@ main(int argc, char *argv[])
printf("INFO: %s\n", "Swapping devices."); printf("INFO: %s\n", "Swapping devices.");
swap_devices = true; swap_devices = true;
} else if (0 == strcmp(argv[arg], "-n")) { } else if (0 == strcmp(argv[arg], "-n")) {
if (++arg == argc || (sscanf(argv[arg], "%i", &waiting_time) < 1)) { if (++arg == argc || (sscanf(argv[arg], "%10i", &waiting_time) < 1)) {
ERR("Missing or wrong waiting time value: %s.", argv[arg]); ERR("Missing or wrong waiting time value: %s.", argv[arg]);
print_usage(argv); print_usage(argv);
return EXIT_FAILURE; exit(EXIT_FAILURE);
} }
printf("Waiting time: %i secs.\n", waiting_time); printf("Waiting time: %i secs.\n", waiting_time);
} else { } else {
ERR("%s is not supported option.", argv[arg]); ERR("%s is not supported option.", argv[arg]);
print_usage(argv); print_usage(argv);
return EXIT_FAILURE; exit(EXIT_FAILURE);
} }
} }
@ -197,6 +199,10 @@ main(int argc, char *argv[])
nfc_context *context; nfc_context *context;
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)");
exit(EXIT_FAILURE);
}
nfc_connstring connstrings[MAX_DEVICE_COUNT]; nfc_connstring connstrings[MAX_DEVICE_COUNT];
// List available devices // List available devices
@ -205,20 +211,24 @@ main(int argc, char *argv[])
if (initiator_only_mode || target_only_mode) { if (initiator_only_mode || target_only_mode) {
if (szFound < 1) { if (szFound < 1) {
ERR("No device found"); ERR("No device found");
return EXIT_FAILURE; nfc_exit(context);
exit(EXIT_FAILURE);
} }
if ((fd3 = fdopen(3, "r")) == NULL) { if ((fd3 = fdopen(3, "r")) == NULL) {
ERR("Could not open file descriptor 3"); ERR("Could not open file descriptor 3");
return EXIT_FAILURE; nfc_exit(context);
exit(EXIT_FAILURE);
} }
if ((fd4 = fdopen(4, "r")) == NULL) { if ((fd4 = fdopen(4, "r")) == NULL) {
ERR("Could not open file descriptor 4"); ERR("Could not open file descriptor 4");
return EXIT_FAILURE; nfc_exit(context);
exit(EXIT_FAILURE);
} }
} else { } else {
if (szFound < 2) { if (szFound < 2) {
ERR("%zd device found but two opened devices are needed to relay NFC.", szFound); ERR("%" PRIdPTR " device found but two opened devices are needed to relay NFC.", szFound);
return EXIT_FAILURE; nfc_exit(context);
exit(EXIT_FAILURE);
} }
} }
@ -234,8 +244,9 @@ main(int argc, char *argv[])
pndInitiator = nfc_open(context, connstrings[1]); pndInitiator = nfc_open(context, connstrings[1]);
} }
if (!pndInitiator) { if (pndInitiator == NULL) {
printf("Error opening NFC reader\n"); printf("Error opening NFC reader\n");
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -261,27 +272,27 @@ main(int argc, char *argv[])
} }
printf("Found tag:\n"); printf("Found tag:\n");
print_nfc_target(ntRealTarget, false); print_nfc_target(&ntRealTarget, false);
if (initiator_only_mode) { if (initiator_only_mode) {
if (print_hex_fd4(ntRealTarget.nti.nai.abtUid, ntRealTarget.nti.nai.szUidLen, "UID") != EXIT_SUCCESS) { if (print_hex_fd4(ntRealTarget.nti.nai.abtUid, ntRealTarget.nti.nai.szUidLen, "UID") < 0) {
fprintf(stderr, "Error while printing UID to FD4\n"); fprintf(stderr, "Error while printing UID to FD4\n");
nfc_close(pndInitiator); nfc_close(pndInitiator);
nfc_exit(context); nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (print_hex_fd4(ntRealTarget.nti.nai.abtAtqa, 2, "ATQA") != EXIT_SUCCESS) { if (print_hex_fd4(ntRealTarget.nti.nai.abtAtqa, 2, "ATQA") < 0) {
fprintf(stderr, "Error while printing ATQA to FD4\n"); fprintf(stderr, "Error while printing ATQA to FD4\n");
nfc_close(pndInitiator); nfc_close(pndInitiator);
nfc_exit(context); nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (print_hex_fd4(&(ntRealTarget.nti.nai.btSak), 1, "SAK") != EXIT_SUCCESS) { if (print_hex_fd4(&(ntRealTarget.nti.nai.btSak), 1, "SAK") < 0) {
fprintf(stderr, "Error while printing SAK to FD4\n"); fprintf(stderr, "Error while printing SAK to FD4\n");
nfc_close(pndInitiator); nfc_close(pndInitiator);
nfc_exit(context); nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (print_hex_fd4(ntRealTarget.nti.nai.abtAts, ntRealTarget.nti.nai.szAtsLen, "ATS") != EXIT_SUCCESS) { if (print_hex_fd4(ntRealTarget.nti.nai.abtAts, ntRealTarget.nti.nai.szAtsLen, "ATS") < 0) {
fprintf(stderr, "Error while printing ATS to FD4\n"); fprintf(stderr, "Error while printing ATS to FD4\n");
nfc_close(pndInitiator); nfc_close(pndInitiator);
nfc_exit(context); nfc_exit(context);
@ -305,24 +316,25 @@ main(int argc, char *argv[])
}; };
if (target_only_mode) { if (target_only_mode) {
size_t foo; size_t foo;
if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtUid, &(ntEmulatedTarget.nti.nai.szUidLen), "UID") != EXIT_SUCCESS) { if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtUid, &(ntEmulatedTarget.nti.nai.szUidLen), "UID") < 0) {
fprintf(stderr, "Error while scanning UID from FD3\n"); fprintf(stderr, "Error while scanning UID from FD3\n");
nfc_close(pndInitiator); nfc_close(pndInitiator);
nfc_exit(context); nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAtqa, &foo, "ATQA") != EXIT_SUCCESS) { if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAtqa, &foo, "ATQA") < 0) {
fprintf(stderr, "Error while scanning ATQA from FD3\n"); fprintf(stderr, "Error while scanning ATQA from FD3\n");
nfc_close(pndInitiator); nfc_close(pndInitiator);
nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (scan_hex_fd3(&(ntEmulatedTarget.nti.nai.btSak), &foo, "SAK") != EXIT_SUCCESS) { if (scan_hex_fd3(&(ntEmulatedTarget.nti.nai.btSak), &foo, "SAK") < 0) {
fprintf(stderr, "Error while scanning SAK from FD3\n"); fprintf(stderr, "Error while scanning SAK from FD3\n");
nfc_close(pndInitiator); nfc_close(pndInitiator);
nfc_exit(context); nfc_exit(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAts, &(ntEmulatedTarget.nti.nai.szAtsLen), "ATS") != EXIT_SUCCESS) { if (scan_hex_fd3(ntEmulatedTarget.nti.nai.abtAts, &(ntEmulatedTarget.nti.nai.szAtsLen), "ATS") < 0) {
fprintf(stderr, "Error while scanning ATS from FD3\n"); fprintf(stderr, "Error while scanning ATS from FD3\n");
nfc_close(pndInitiator); nfc_close(pndInitiator);
nfc_exit(context); nfc_exit(context);
@ -361,7 +373,7 @@ main(int argc, char *argv[])
memcpy(&(ntEmulatedTarget.nti.nai.abtAts[4]), pbtTkt, szTk); memcpy(&(ntEmulatedTarget.nti.nai.abtAts[4]), pbtTkt, szTk);
printf("We will emulate:\n"); printf("We will emulate:\n");
print_nfc_target(ntEmulatedTarget, false); print_nfc_target(&ntEmulatedTarget, false);
// Try to open the NFC emulator device // Try to open the NFC emulator device
if (swap_devices) { if (swap_devices) {
@ -375,12 +387,11 @@ main(int argc, char *argv[])
nfc_close(pndInitiator); nfc_close(pndInitiator);
} }
nfc_exit(context); nfc_exit(context);
return EXIT_FAILURE; exit(EXIT_FAILURE);
} }
printf("NFC emulator device: %s opened\n", nfc_device_get_name(pndTarget)); printf("NFC emulator device: %s opened\n", nfc_device_get_name(pndTarget));
int res; if (nfc_target_init(pndTarget, &ntEmulatedTarget, abtCapdu, sizeof(abtCapdu), 0) < 0) {
if ((res = nfc_target_init(pndTarget, &ntEmulatedTarget, abtCapdu, sizeof(abtCapdu), 0)) < 0) {
ERR("%s", "Initialization of NFC emulator failed"); ERR("%s", "Initialization of NFC emulator failed");
if (!target_only_mode) { if (!target_only_mode) {
nfc_close(pndInitiator); nfc_close(pndInitiator);
@ -408,7 +419,7 @@ main(int argc, char *argv[])
} }
szCapduLen = (size_t) res; szCapduLen = (size_t) res;
if (target_only_mode) { if (target_only_mode) {
if (print_hex_fd4(abtCapdu, szCapduLen, "C-APDU") != EXIT_SUCCESS) { if (print_hex_fd4(abtCapdu, szCapduLen, "C-APDU") < 0) {
fprintf(stderr, "Error while printing C-APDU to FD4\n"); fprintf(stderr, "Error while printing C-APDU to FD4\n");
nfc_close(pndTarget); nfc_close(pndTarget);
nfc_exit(context); nfc_exit(context);
@ -416,7 +427,7 @@ main(int argc, char *argv[])
} }
} }
} else { } else {
if (scan_hex_fd3(abtCapdu, &szCapduLen, "C-APDU") != EXIT_SUCCESS) { if (scan_hex_fd3(abtCapdu, &szCapduLen, "C-APDU") < 0) {
fprintf(stderr, "Error while scanning C-APDU from FD3\n"); fprintf(stderr, "Error while scanning C-APDU from FD3\n");
nfc_close(pndInitiator); nfc_close(pndInitiator);
nfc_exit(context); nfc_exit(context);
@ -438,7 +449,7 @@ main(int argc, char *argv[])
ret = true; ret = true;
} }
} else { } else {
if (scan_hex_fd3(abtRapdu, &szRapduLen, "R-APDU") != EXIT_SUCCESS) { if (scan_hex_fd3(abtRapdu, &szRapduLen, "R-APDU") < 0) {
fprintf(stderr, "Error while scanning R-APDU from FD3\n"); fprintf(stderr, "Error while scanning R-APDU from FD3\n");
nfc_close(pndTarget); nfc_close(pndTarget);
nfc_exit(context); nfc_exit(context);
@ -474,7 +485,7 @@ main(int argc, char *argv[])
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} else { } else {
if (print_hex_fd4(abtRapdu, szRapduLen, "R-APDU") != EXIT_SUCCESS) { if (print_hex_fd4(abtRapdu, szRapduLen, "R-APDU") < 0) {
fprintf(stderr, "Error while printing R-APDU to FD4\n"); fprintf(stderr, "Error while printing R-APDU to FD4\n");
nfc_close(pndInitiator); nfc_close(pndInitiator);
nfc_exit(context); nfc_exit(context);

View file

@ -76,7 +76,7 @@ main(int argc, const char *argv[])
for (int arg = 1; arg < argc; arg++) { for (int arg = 1; arg < argc; arg++) {
if (0 == strcmp(argv[arg], "-h")) { if (0 == strcmp(argv[arg], "-h")) {
print_usage(argv); print_usage(argv);
return EXIT_SUCCESS; exit(EXIT_SUCCESS);
} else if (0 == strcmp(argv[arg], "-v")) { } else if (0 == strcmp(argv[arg], "-v")) {
verbose = true; verbose = true;
} else if (0 == strcmp(argv[arg], "-i")) { } else if (0 == strcmp(argv[arg], "-i")) {
@ -85,11 +85,15 @@ main(int argc, const char *argv[])
} else { } else {
ERR("%s is not supported option.", argv[arg]); ERR("%s is not supported option.", argv[arg]);
print_usage(argv); print_usage(argv);
return EXIT_FAILURE; exit(EXIT_FAILURE);
} }
} }
nfc_init(&context); nfc_init(&context);
if (context == NULL) {
ERR("Unable to init libnfc (malloc)\n");
exit(EXIT_FAILURE);
}
// Display libnfc version // Display libnfc version
acLibnfcVersion = nfc_version(); acLibnfcVersion = nfc_version();
@ -98,10 +102,10 @@ main(int argc, const char *argv[])
nfc_connstring connstrings[MAX_DEVICE_COUNT]; nfc_connstring connstrings[MAX_DEVICE_COUNT];
size_t szDeviceFound = nfc_list_devices(context, connstrings, MAX_DEVICE_COUNT); size_t szDeviceFound = nfc_list_devices(context, connstrings, MAX_DEVICE_COUNT);
int res = EXIT_FAILURE;
if (szDeviceFound == 0) { if (szDeviceFound == 0) {
printf("No NFC device found.\n"); printf("No NFC device found.\n");
goto bye; nfc_exit(context);
exit(EXIT_FAILURE);
} }
printf("%d NFC device(s) found:\n", (int)szDeviceFound); printf("%d NFC device(s) found:\n", (int)szDeviceFound);
@ -121,9 +125,6 @@ main(int argc, const char *argv[])
printf("nfc_open failed for %s\n", connstrings[i]); printf("nfc_open failed for %s\n", connstrings[i]);
} }
} }
res = EXIT_SUCCESS;
bye:
nfc_exit(context); nfc_exit(context);
return res; exit(EXIT_SUCCESS);
} }

View file

@ -115,10 +115,10 @@ print_hex_par(const uint8_t *pbtData, const size_t szBits, const uint8_t *pbtDat
} }
void void
print_nfc_target(const nfc_target nt, bool verbose) print_nfc_target(const nfc_target *pnt, bool verbose)
{ {
char *s; char *s;
str_nfc_target(&s, nt, verbose); str_nfc_target(&s, pnt, verbose);
printf("%s", s); printf("%s", s);
nfc_free(s); nfc_free(s);
} }

View file

@ -94,6 +94,6 @@ 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_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_hex_par(const uint8_t *pbtData, const size_t szBits, const uint8_t *pbtDataPar);
void print_nfc_target(const nfc_target nt, bool verbose); void print_nfc_target(const nfc_target *pnt, bool verbose);
#endif #endif