Merge branch 'master' into pn532_spi
* master: (28 commits) Update Changelog Add missing windows files in archive Move log implementation for Windows in dedicated directory Move UART implementation for Windows in dedicated directory CMake: only compile usbbus.c when (at least) one USB driver is enabled CMake: only include UART related files when (at least) one UART driver is enabled Only include UART related files when (at least) one UART driver is enabled Fix environment vars usage when compiling with CMake Remove unsed code section in log.c (was commented) pn53x_current_target_new() now returns null ptr upon malloc() error fix missing tests on malloc() return pn53x_data_new() now returns null ptr upon malloc() error uart drivers: missing pn53x_data_free() on some error handling branches uart drivers: missing nfc_device_free() on some error handling branches uart drivers: missing uart_close() on some error handling branches uart drivers: fix missing free(ndd.port) config parser: missing fclose() UART drivers: fix double free() of serial port info Fix cmake build failure under linux quick_start_example1.c: avoid using warnx() to remove err.h dependency ... Conflicts: libnfc/buses/Makefile.am
This commit is contained in:
commit
1417bdc164
29 changed files with 645 additions and 512 deletions
|
@ -34,6 +34,11 @@ IF(LIBNFC_LOG)
|
|||
ADD_DEFINITIONS(-DLOG)
|
||||
ENDIF(LIBNFC_LOG)
|
||||
|
||||
SET(LIBNFC_ENVVARS ON CACHE BOOL "Enable envvars facility")
|
||||
IF(LIBNFC_ENVVARS)
|
||||
ADD_DEFINITIONS(-DENVVARS)
|
||||
ENDIF(LIBNFC_ENVVARS)
|
||||
|
||||
SET(LIBNFC_DEBUG_MODE OFF CACHE BOOL "Debug mode")
|
||||
IF(LIBNFC_DEBUG_MODE)
|
||||
ADD_DEFINITIONS(-DDEBUG)
|
||||
|
@ -111,6 +116,8 @@ IF (WIN32)
|
|||
ENDIF(PCRE_INCLUDE_DIRS)
|
||||
ENDIF(WIN32)
|
||||
|
||||
INCLUDE(LibnfcDrivers)
|
||||
|
||||
IF(PCSC_INCLUDE_DIRS)
|
||||
INCLUDE_DIRECTORIES(${PCSC_INCLUDE_DIRS})
|
||||
LINK_DIRECTORIES(${PCSC_LIBRARY_DIRS})
|
||||
|
|
|
@ -14,15 +14,24 @@ Fixes:
|
|||
- scanf without field width limits can crash with huge input data
|
||||
- Resource leaks: missing fclose()
|
||||
- Dead code, unused vars & vars scopes warnings
|
||||
- Unify copyright notices & update authors lists
|
||||
- Windows: Fix compilation due to new usbbus file
|
||||
- Windows: Clean up compiler/linker warnings
|
||||
- Fixed the suppression of the auto-fixup for linking against MS built libs
|
||||
- Fixed all the formatting warnings by shifting to inttypes.h specifiers
|
||||
- shifted to %lu for DWORD printf
|
||||
- nfc-anticol: fix ATS length
|
||||
- nfc-mfclassic: fix reporting of processed blocks total
|
||||
- nfc-mfclassic: detect MIFARE Plus 2K as 2K instead of 1K
|
||||
|
||||
Improvements:
|
||||
- Devels HACKING file: introduce clang/scan-build & cppcheck for better code
|
||||
- Better internal dependencies handling (bus <> drivers)
|
||||
- Cleaner handling of portability patches
|
||||
- Windows: logging via OutputDebugString(), ease debugging
|
||||
- nfc-mfclassic: use smaller files for cards < 4k
|
||||
- nfc-mfclassic: by defaut don't authorise wrong keyfile, use "f" to force
|
||||
- quick_start_example1.c: remove err.h dependency, easier for Windowsians
|
||||
|
||||
Changes:
|
||||
- Upon malloc error, nfc_init() doesn't force exit() anymore
|
||||
|
|
|
@ -14,16 +14,19 @@ IF(LIBNFC_DRIVER_PN53X_USB)
|
|||
FIND_PACKAGE(LIBUSB REQUIRED)
|
||||
ADD_DEFINITIONS("-DDRIVER_PN53X_USB_ENABLED")
|
||||
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/pn53x_usb")
|
||||
SET(USB_REQUIRED TRUE)
|
||||
ENDIF(LIBNFC_DRIVER_PN53X_USB)
|
||||
|
||||
IF(LIBNFC_DRIVER_ARYGON)
|
||||
ADD_DEFINITIONS("-DDRIVER_ARYGON_ENABLED")
|
||||
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/arygon")
|
||||
SET(UART_REQUIRED TRUE)
|
||||
ENDIF(LIBNFC_DRIVER_ARYGON)
|
||||
|
||||
IF(LIBNFC_DRIVER_PN532_UART)
|
||||
ADD_DEFINITIONS("-DDRIVER_PN532_UART_ENABLED")
|
||||
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/pn532_uart")
|
||||
SET(UART_REQUIRED TRUE)
|
||||
ENDIF(LIBNFC_DRIVER_PN532_UART)
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/drivers)
|
||||
|
|
|
@ -118,6 +118,9 @@ fi
|
|||
# Handle --with-drivers option
|
||||
LIBNFC_ARG_WITH_DRIVERS
|
||||
|
||||
# Enable UART if
|
||||
AM_CONDITIONAL(UART_ENABLED, [test x"$uart_required" = x"yes"])
|
||||
|
||||
# Documentation (default: no)
|
||||
AC_ARG_ENABLE([doc],AS_HELP_STRING([--enable-doc],[Enable documentation generation.]),[enable_doc=$enableval],[enable_doc="no"])
|
||||
|
||||
|
@ -175,6 +178,8 @@ AC_CONFIG_FILES([
|
|||
contrib/udev/Makefile
|
||||
contrib/win32/Makefile
|
||||
contrib/win32/sys/Makefile
|
||||
contrib/win32/libnfc/Makefile
|
||||
contrib/win32/libnfc/buses/Makefile
|
||||
examples/Makefile
|
||||
examples/pn53x-tamashell-scripts/Makefile
|
||||
include/Makefile
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
SUBDIRS = sys .
|
||||
SUBDIRS = libnfc sys .
|
||||
|
||||
EXTRA_DIST = \
|
||||
err.h \
|
||||
|
|
4
contrib/win32/libnfc/Makefile.am
Normal file
4
contrib/win32/libnfc/Makefile.am
Normal file
|
@ -0,0 +1,4 @@
|
|||
SUBDIRS = buses .
|
||||
|
||||
EXTRA_DIST = \
|
||||
log-internal.c
|
2
contrib/win32/libnfc/buses/Makefile.am
Normal file
2
contrib/win32/libnfc/buses/Makefile.am
Normal file
|
@ -0,0 +1,2 @@
|
|||
EXTRA_DIST = \
|
||||
uart.c
|
|
@ -25,10 +25,19 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file uart_win32.c
|
||||
* @file uart.c
|
||||
* @brief Windows UART driver
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include "uart.h"
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
#include "nfc-internal.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "log.h"
|
||||
|
||||
|
@ -250,11 +259,19 @@ char **
|
|||
uart_list_ports(void)
|
||||
{
|
||||
char **availablePorts = malloc((1 + MAX_SERIAL_PORT_WIN) * sizeof(char *));
|
||||
if (!availablePorts) {
|
||||
perror("malloc");
|
||||
return availablePorts;
|
||||
}
|
||||
int curIndex = 0;
|
||||
int i;
|
||||
for (i = 1; i <= MAX_SERIAL_PORT_WIN; i++) {
|
||||
if (is_port_available(i)) {
|
||||
availablePorts[curIndex] = (char *)malloc(10);
|
||||
if (!availablePorts[curIndex]) {
|
||||
perror("malloc");
|
||||
break;
|
||||
}
|
||||
sprintf(availablePorts[curIndex], "COM%d", i);
|
||||
// printf("found candidate port: %s\n", availablePorts[curIndex]);
|
||||
curIndex++;
|
|
@ -6,12 +6,7 @@
|
|||
// To compile this simple example:
|
||||
// $ gcc -o quick_start_example1 quick_start_example1.c -lnfc
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <err.h>
|
||||
#include <nfc/nfc.h>
|
||||
|
||||
static void
|
||||
|
@ -37,7 +32,7 @@ main(int argc, const char *argv[])
|
|||
// Initialize libnfc and set the nfc_context
|
||||
nfc_init(&context);
|
||||
if (context == NULL) {
|
||||
warnx("Unable to init libnfc (malloc)\n");
|
||||
printf("Unable to init libnfc (malloc)\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
@ -53,7 +48,7 @@ main(int argc, const char *argv[])
|
|||
pnd = nfc_open(context, NULL);
|
||||
|
||||
if (pnd == NULL) {
|
||||
warnx("ERROR: %s", "Unable to open NFC device.");
|
||||
printf("ERROR: %s", "Unable to open NFC device.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// Set opened NFC device to initiator mode
|
||||
|
|
|
@ -114,11 +114,11 @@ transmit_bytes(const uint8_t *pbtTx, const size_t szTx)
|
|||
// Transmit the command bytes
|
||||
if ((res = nfc_initiator_transceive_bytes(pnd, pbtTx, szTx, abtRx, sizeof(abtRx), 0)) < 0)
|
||||
return false;
|
||||
|
||||
szRx = res;
|
||||
// Show received answer
|
||||
if (!quiet_output) {
|
||||
printf("Received bits: ");
|
||||
print_hex(abtRx, res);
|
||||
print_hex(abtRx, szRx);
|
||||
}
|
||||
// Succesful transfer
|
||||
return true;
|
||||
|
|
|
@ -12,14 +12,20 @@ SET(CHIPS_SOURCES chips/pn53x)
|
|||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/chips)
|
||||
|
||||
# Library's buses
|
||||
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)
|
||||
IF(USB_REQUIRED)
|
||||
LIST(APPEND BUSES_SOURCES buses/usbbus)
|
||||
ENDIF(USB_REQUIRED)
|
||||
|
||||
INCLUDE(LibnfcDrivers)
|
||||
IF(UART_REQUIRED)
|
||||
IF(WIN32)
|
||||
# Windows have a special implementation for UART
|
||||
LIST(APPEND BUSES_SOURCES ../contrib/win32/libnfc/buses/uart)
|
||||
ELSE(WIN32)
|
||||
LIST(APPEND BUSES_SOURCES buses/uart)
|
||||
ENDIF(WIN32)
|
||||
ENDIF(UART_REQUIRED)
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/buses)
|
||||
|
||||
IF(WIN32)
|
||||
# Windows now requires regex, so we utilize PCRE
|
||||
|
@ -42,15 +48,15 @@ IF(LIBUSB_FOUND)
|
|||
ENDIF(LIBUSB_FOUND)
|
||||
|
||||
# Library
|
||||
SET(LIBRARY_SOURCES nfc nfc-device nfc-emulation nfc-internal conf iso14443-subr mirror-subr target-subr log ${DRIVERS_SOURCES} ${BUSES_SOURCES} ${CHIPS_SOURCES} ${WINDOWS_SOURCES})
|
||||
SET(LIBRARY_SOURCES nfc nfc-device nfc-emulation nfc-internal conf iso14443-subr mirror-subr target-subr ${DRIVERS_SOURCES} ${BUSES_SOURCES} ${CHIPS_SOURCES} ${WINDOWS_SOURCES})
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
IF(LIBNFC_LOG)
|
||||
IF(WIN32)
|
||||
SET(CMAKE_C_FLAGS "-fgnu89-inline ${CMAKE_C_FLAGS}")
|
||||
LIST(APPEND LIBRARY_SOURCES log_win32)
|
||||
LIST(APPEND LIBRARY_SOURCES log ../contrib/win32/libnfc/log-internal)
|
||||
ELSE(WIN32)
|
||||
LIST(APPEND LIBRARY_SOURCES log_posix)
|
||||
LIST(APPEND LIBRARY_SOURCES log log-internal)
|
||||
ENDIF(WIN32)
|
||||
ENDIF(LIBNFC_LOG)
|
||||
ADD_LIBRARY(nfc SHARED ${LIBRARY_SOURCES})
|
||||
|
|
|
@ -7,7 +7,6 @@ lib_LTLIBRARIES = libnfc.la
|
|||
libnfc_la_SOURCES = \
|
||||
conf.c \
|
||||
iso14443-subr.c \
|
||||
log.c \
|
||||
mirror-subr.c \
|
||||
nfc.c \
|
||||
nfc-device.c \
|
||||
|
@ -41,10 +40,8 @@ if LIBUSB_ENABLED
|
|||
endif
|
||||
|
||||
if WITH_LOG
|
||||
libnfc_la_SOURCES += log_posix.c
|
||||
libnfc_la_SOURCES += log.c log-internal.c
|
||||
endif
|
||||
|
||||
EXTRA_DIST = \
|
||||
CMakeLists.txt \
|
||||
log_posix.c \
|
||||
log_win32.c
|
||||
CMakeLists.txt
|
||||
|
|
|
@ -6,6 +6,7 @@ noinst_LTLIBRARIES = libnfcbuses.la
|
|||
libnfcbuses_la_SOURCES =
|
||||
libnfcbuses_la_CFLAGS = -I$(top_srcdir)/libnfc
|
||||
libnfcbuses_la_LIBADD =
|
||||
EXTRA_DIST =
|
||||
|
||||
# SPI_ENABLED
|
||||
libnfcbuses_la_SOURCES += spi.c spi.h
|
||||
|
@ -13,11 +14,12 @@ 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 UART_ENABLED
|
||||
libnfcbuses_la_SOURCES += uart.c uart.h
|
||||
libnfcbuses_la_CFLAGS +=
|
||||
libnfcbuses_la_LIBADD +=
|
||||
endif
|
||||
EXTRA_DIST += uart.c uart.h
|
||||
|
||||
if LIBUSB_ENABLED
|
||||
libnfcbuses_la_SOURCES += usbbus.c usbbus.h
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
/**
|
||||
* @file uart.c
|
||||
* @brief UART driver wrapper
|
||||
* @brief UART driver
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -35,14 +35,362 @@
|
|||
|
||||
#include "uart.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
#include "nfc-internal.h"
|
||||
|
||||
// Test if we are dealing with unix operating systems
|
||||
#ifndef _WIN32
|
||||
// The POSIX serial port implementation
|
||||
# include "uart_posix.c"
|
||||
#else
|
||||
// The windows serial port implementation
|
||||
# include "uart_win32.c"
|
||||
#endif /* _WIN32 */
|
||||
#define LOG_GROUP NFC_LOG_GROUP_COM
|
||||
#define LOG_CATEGORY "libnfc.bus.uart"
|
||||
|
||||
# if defined(__APPLE__)
|
||||
const char *serial_ports_device_radix[] = { "tty.SLAB_USBtoUART", "tty.usbserial-", NULL };
|
||||
# elif defined (__FreeBSD__) || defined (__OpenBSD__)
|
||||
const char *serial_ports_device_radix[] = { "cuaU", "cuau", NULL };
|
||||
# elif defined (__linux__)
|
||||
const char *serial_ports_device_radix[] = { "ttyUSB", "ttyS", "ttyACM", "ttyAMA", NULL };
|
||||
# else
|
||||
# error "Can't determine serial string for your system"
|
||||
# endif
|
||||
|
||||
// Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct
|
||||
# define CCLAIMED 0x80000000
|
||||
|
||||
struct serial_port_unix {
|
||||
int fd; // Serial port file descriptor
|
||||
struct termios termios_backup; // Terminal info before using the port
|
||||
struct termios termios_new; // Terminal info during the transaction
|
||||
};
|
||||
|
||||
#define UART_DATA( X ) ((struct serial_port_unix *) X)
|
||||
|
||||
void uart_close_ext(const serial_port sp, const bool restore_termios);
|
||||
|
||||
serial_port
|
||||
uart_open(const char *pcPortName)
|
||||
{
|
||||
struct serial_port_unix *sp = malloc(sizeof(struct serial_port_unix));
|
||||
|
||||
if (sp == 0)
|
||||
return INVALID_SERIAL_PORT;
|
||||
|
||||
sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
if (sp->fd == -1) {
|
||||
uart_close_ext(sp, false);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
|
||||
if (tcgetattr(sp->fd, &sp->termios_backup) == -1) {
|
||||
uart_close_ext(sp, false);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
// Make sure the port is not claimed already
|
||||
if (sp->termios_backup.c_iflag & CCLAIMED) {
|
||||
uart_close_ext(sp, false);
|
||||
return CLAIMED_SERIAL_PORT;
|
||||
}
|
||||
// Copy the old terminal info struct
|
||||
sp->termios_new = sp->termios_backup;
|
||||
|
||||
sp->termios_new.c_cflag = CS8 | CLOCAL | CREAD;
|
||||
sp->termios_new.c_iflag = CCLAIMED | IGNPAR;
|
||||
sp->termios_new.c_oflag = 0;
|
||||
sp->termios_new.c_lflag = 0;
|
||||
|
||||
sp->termios_new.c_cc[VMIN] = 0; // block until n bytes are received
|
||||
sp->termios_new.c_cc[VTIME] = 0; // block until a timer expires (n * 100 mSec.)
|
||||
|
||||
if (tcsetattr(sp->fd, TCSANOW, &sp->termios_new) == -1) {
|
||||
uart_close_ext(sp, true);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
return sp;
|
||||
}
|
||||
|
||||
void
|
||||
uart_flush_input(serial_port sp)
|
||||
{
|
||||
// This line seems to produce absolutely no effect on my system (GNU/Linux 2.6.35)
|
||||
tcflush(UART_DATA(sp)->fd, TCIFLUSH);
|
||||
// So, I wrote this byte-eater
|
||||
// Retrieve the count of the incoming bytes
|
||||
int available_bytes_count = 0;
|
||||
int res;
|
||||
res = ioctl(UART_DATA(sp)->fd, FIONREAD, &available_bytes_count);
|
||||
if (res != 0) {
|
||||
return;
|
||||
}
|
||||
if (available_bytes_count == 0) {
|
||||
return;
|
||||
}
|
||||
char *rx = malloc(available_bytes_count);
|
||||
if (!rx) {
|
||||
perror("malloc");
|
||||
return;
|
||||
}
|
||||
// There is something available, read the data
|
||||
(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);
|
||||
free(rx);
|
||||
}
|
||||
|
||||
void
|
||||
uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
||||
{
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
||||
|
||||
// Portability note: on some systems, B9600 != 9600 so we have to do
|
||||
// uint32_t <=> speed_t associations by hand.
|
||||
speed_t stPortSpeed = B9600;
|
||||
switch (uiPortSpeed) {
|
||||
case 9600:
|
||||
stPortSpeed = B9600;
|
||||
break;
|
||||
case 19200:
|
||||
stPortSpeed = B19200;
|
||||
break;
|
||||
case 38400:
|
||||
stPortSpeed = B38400;
|
||||
break;
|
||||
# ifdef B57600
|
||||
case 57600:
|
||||
stPortSpeed = B57600;
|
||||
break;
|
||||
# endif
|
||||
# ifdef B115200
|
||||
case 115200:
|
||||
stPortSpeed = B115200;
|
||||
break;
|
||||
# endif
|
||||
# ifdef B230400
|
||||
case 230400:
|
||||
stPortSpeed = B230400;
|
||||
break;
|
||||
# endif
|
||||
# ifdef B460800
|
||||
case 460800:
|
||||
stPortSpeed = B460800;
|
||||
break;
|
||||
# endif
|
||||
default:
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to set serial port speed to %d bauds. Speed value must be one of those defined in termios(3).",
|
||||
uiPortSpeed);
|
||||
return;
|
||||
};
|
||||
|
||||
// Set port speed (Input and Output)
|
||||
cfsetispeed(&(UART_DATA(sp)->termios_new), stPortSpeed);
|
||||
cfsetospeed(&(UART_DATA(sp)->termios_new), stPortSpeed);
|
||||
if (tcsetattr(UART_DATA(sp)->fd, TCSADRAIN, &(UART_DATA(sp)->termios_new)) == -1) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to apply new speed settings.");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
uart_get_speed(serial_port sp)
|
||||
{
|
||||
uint32_t uiPortSpeed = 0;
|
||||
switch (cfgetispeed(&UART_DATA(sp)->termios_new)) {
|
||||
case B9600:
|
||||
uiPortSpeed = 9600;
|
||||
break;
|
||||
case B19200:
|
||||
uiPortSpeed = 19200;
|
||||
break;
|
||||
case B38400:
|
||||
uiPortSpeed = 38400;
|
||||
break;
|
||||
# ifdef B57600
|
||||
case B57600:
|
||||
uiPortSpeed = 57600;
|
||||
break;
|
||||
# endif
|
||||
# ifdef B115200
|
||||
case B115200:
|
||||
uiPortSpeed = 115200;
|
||||
break;
|
||||
# endif
|
||||
# ifdef B230400
|
||||
case B230400:
|
||||
uiPortSpeed = 230400;
|
||||
break;
|
||||
# endif
|
||||
# ifdef B460800
|
||||
case B460800:
|
||||
uiPortSpeed = 460800;
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
|
||||
return uiPortSpeed;
|
||||
}
|
||||
|
||||
void
|
||||
uart_close_ext(const serial_port sp, const bool restore_termios)
|
||||
{
|
||||
if (UART_DATA(sp)->fd >= 0) {
|
||||
if (restore_termios)
|
||||
tcsetattr(UART_DATA(sp)->fd, TCSANOW, &UART_DATA(sp)->termios_backup);
|
||||
close(UART_DATA(sp)->fd);
|
||||
}
|
||||
free(sp);
|
||||
}
|
||||
|
||||
void
|
||||
uart_close(const serial_port sp)
|
||||
{
|
||||
uart_close_ext(sp, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive data from UART and copy data to \a pbtRx
|
||||
*
|
||||
* @return 0 on success, otherwise driver error code
|
||||
*/
|
||||
int
|
||||
uart_receive(serial_port sp, uint8_t *pbtRx, const size_t szRx, void *abort_p, int timeout)
|
||||
{
|
||||
int iAbortFd = abort_p ? *((int *)abort_p) : 0;
|
||||
int received_bytes_count = 0;
|
||||
int available_bytes_count = 0;
|
||||
const int expected_bytes_count = (int)szRx;
|
||||
int res;
|
||||
fd_set rfds;
|
||||
do {
|
||||
select:
|
||||
// Reset file descriptor
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(UART_DATA(sp)->fd, &rfds);
|
||||
|
||||
if (iAbortFd) {
|
||||
FD_SET(iAbortFd, &rfds);
|
||||
}
|
||||
|
||||
struct timeval timeout_tv;
|
||||
if (timeout > 0) {
|
||||
timeout_tv.tv_sec = (timeout / 1000);
|
||||
timeout_tv.tv_usec = ((timeout % 1000) * 1000);
|
||||
}
|
||||
|
||||
res = select(MAX(UART_DATA(sp)->fd, iAbortFd) + 1, &rfds, NULL, NULL, timeout ? &timeout_tv : NULL);
|
||||
|
||||
if ((res < 0) && (EINTR == errno)) {
|
||||
// The system call was interupted by a signal and a signal handler was
|
||||
// run. Restart the interupted system call.
|
||||
goto select;
|
||||
}
|
||||
|
||||
// Read error
|
||||
if (res < 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Error: %s", strerror(errno));
|
||||
return NFC_EIO;
|
||||
}
|
||||
// Read time-out
|
||||
if (res == 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "Timeout!");
|
||||
return NFC_ETIMEOUT;
|
||||
}
|
||||
|
||||
if (FD_ISSET(iAbortFd, &rfds)) {
|
||||
// Abort requested
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "Abort!");
|
||||
close(iAbortFd);
|
||||
return NFC_EOPABORTED;
|
||||
}
|
||||
|
||||
// Retrieve the count of the incoming bytes
|
||||
res = ioctl(UART_DATA(sp)->fd, FIONREAD, &available_bytes_count);
|
||||
if (res != 0) {
|
||||
return NFC_EIO;
|
||||
}
|
||||
// There is something available, read the data
|
||||
res = read(UART_DATA(sp)->fd, pbtRx + received_bytes_count, MIN(available_bytes_count, (expected_bytes_count - received_bytes_count)));
|
||||
// Stop if the OS has some troubles reading the data
|
||||
if (res <= 0) {
|
||||
return NFC_EIO;
|
||||
}
|
||||
received_bytes_count += res;
|
||||
|
||||
} while (expected_bytes_count > received_bytes_count);
|
||||
LOG_HEX(LOG_GROUP, "RX", pbtRx, szRx);
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send \a pbtTx content to UART
|
||||
*
|
||||
* @return 0 on success, otherwise a driver error is returned
|
||||
*/
|
||||
int
|
||||
uart_send(serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout)
|
||||
{
|
||||
(void) timeout;
|
||||
LOG_HEX(LOG_GROUP, "TX", pbtTx, szTx);
|
||||
if ((int) szTx == write(UART_DATA(sp)->fd, pbtTx, szTx))
|
||||
return NFC_SUCCESS;
|
||||
else
|
||||
return NFC_EIO;
|
||||
}
|
||||
|
||||
char **
|
||||
uart_list_ports(void)
|
||||
{
|
||||
char **res = malloc(sizeof(char *));
|
||||
if (!res) {
|
||||
perror("malloc");
|
||||
return res;
|
||||
}
|
||||
size_t szRes = 1;
|
||||
|
||||
res[0] = NULL;
|
||||
DIR *dir;
|
||||
if ((dir = opendir("/dev")) == NULL) {
|
||||
perror("opendir error: /dev");
|
||||
return res;
|
||||
}
|
||||
struct dirent entry;
|
||||
struct dirent *result;
|
||||
while ((readdir_r(dir, &entry, &result) == 0) && (result != NULL)) {
|
||||
#if !defined(__APPLE__)
|
||||
if (!isdigit(entry.d_name[strlen(entry.d_name) - 1]))
|
||||
continue;
|
||||
#endif
|
||||
const char **p = serial_ports_device_radix;
|
||||
while (*p) {
|
||||
if (!strncmp(entry.d_name, *p, strlen(*p))) {
|
||||
char **res2 = realloc(res, (szRes + 1) * sizeof(char *));
|
||||
if (!res2) {
|
||||
perror("malloc");
|
||||
goto oom;
|
||||
}
|
||||
res = res2;
|
||||
if (!(res[szRes - 1] = malloc(6 + strlen(entry.d_name)))) {
|
||||
perror("malloc");
|
||||
goto oom;
|
||||
}
|
||||
sprintf(res[szRes - 1], "/dev/%s", entry.d_name);
|
||||
|
||||
szRes++;
|
||||
res[szRes - 1] = NULL;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
oom:
|
||||
closedir(dir);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1,381 +0,0 @@
|
|||
/*-
|
||||
* Free/Libre Near Field Communication (NFC) library
|
||||
*
|
||||
* Libnfc historical contributors:
|
||||
* Copyright (C) 2009 Roel Verdult
|
||||
* Copyright (C) 2009-2013 Romuald Conty
|
||||
* Copyright (C) 2010-2012 Romain Tartière
|
||||
* Copyright (C) 2010-2013 Philippe Teuwen
|
||||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||
* Additional contributors of this file:
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file uart_posix.c
|
||||
* @brief POSIX UART driver
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nfc-internal.h"
|
||||
|
||||
#define LOG_GROUP NFC_LOG_GROUP_COM
|
||||
#define LOG_CATEGORY "libnfc.bus.uart"
|
||||
|
||||
# if defined(__APPLE__)
|
||||
const char *serial_ports_device_radix[] = { "tty.SLAB_USBtoUART", "tty.usbserial-", NULL };
|
||||
# elif defined (__FreeBSD__) || defined (__OpenBSD__)
|
||||
const char *serial_ports_device_radix[] = { "cuaU", "cuau", NULL };
|
||||
# elif defined (__linux__)
|
||||
const char *serial_ports_device_radix[] = { "ttyUSB", "ttyS", "ttyACM", "ttyAMA", NULL };
|
||||
# else
|
||||
# error "Can't determine serial string for your system"
|
||||
# endif
|
||||
|
||||
// Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct
|
||||
# define CCLAIMED 0x80000000
|
||||
|
||||
struct serial_port_unix {
|
||||
int fd; // Serial port file descriptor
|
||||
struct termios termios_backup; // Terminal info before using the port
|
||||
struct termios termios_new; // Terminal info during the transaction
|
||||
};
|
||||
|
||||
#define UART_DATA( X ) ((struct serial_port_unix *) X)
|
||||
|
||||
void uart_close_ext(const serial_port sp, const bool restore_termios);
|
||||
|
||||
serial_port
|
||||
uart_open(const char *pcPortName)
|
||||
{
|
||||
struct serial_port_unix *sp = malloc(sizeof(struct serial_port_unix));
|
||||
|
||||
if (sp == 0)
|
||||
return INVALID_SERIAL_PORT;
|
||||
|
||||
sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
if (sp->fd == -1) {
|
||||
uart_close_ext(sp, false);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
|
||||
if (tcgetattr(sp->fd, &sp->termios_backup) == -1) {
|
||||
uart_close_ext(sp, false);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
// Make sure the port is not claimed already
|
||||
if (sp->termios_backup.c_iflag & CCLAIMED) {
|
||||
uart_close_ext(sp, false);
|
||||
return CLAIMED_SERIAL_PORT;
|
||||
}
|
||||
// Copy the old terminal info struct
|
||||
sp->termios_new = sp->termios_backup;
|
||||
|
||||
sp->termios_new.c_cflag = CS8 | CLOCAL | CREAD;
|
||||
sp->termios_new.c_iflag = CCLAIMED | IGNPAR;
|
||||
sp->termios_new.c_oflag = 0;
|
||||
sp->termios_new.c_lflag = 0;
|
||||
|
||||
sp->termios_new.c_cc[VMIN] = 0; // block until n bytes are received
|
||||
sp->termios_new.c_cc[VTIME] = 0; // block until a timer expires (n * 100 mSec.)
|
||||
|
||||
if (tcsetattr(sp->fd, TCSANOW, &sp->termios_new) == -1) {
|
||||
uart_close_ext(sp, true);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
return sp;
|
||||
}
|
||||
|
||||
void
|
||||
uart_flush_input(serial_port sp)
|
||||
{
|
||||
// This line seems to produce absolutely no effect on my system (GNU/Linux 2.6.35)
|
||||
tcflush(UART_DATA(sp)->fd, TCIFLUSH);
|
||||
// So, I wrote this byte-eater
|
||||
// Retrieve the count of the incoming bytes
|
||||
int available_bytes_count = 0;
|
||||
int res;
|
||||
res = ioctl(UART_DATA(sp)->fd, FIONREAD, &available_bytes_count);
|
||||
if (res != 0) {
|
||||
return;
|
||||
}
|
||||
if (available_bytes_count == 0) {
|
||||
return;
|
||||
}
|
||||
char *rx = malloc(available_bytes_count);
|
||||
// There is something available, read the data
|
||||
(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);
|
||||
free(rx);
|
||||
}
|
||||
|
||||
void
|
||||
uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
||||
{
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
||||
|
||||
// Portability note: on some systems, B9600 != 9600 so we have to do
|
||||
// uint32_t <=> speed_t associations by hand.
|
||||
speed_t stPortSpeed = B9600;
|
||||
switch (uiPortSpeed) {
|
||||
case 9600:
|
||||
stPortSpeed = B9600;
|
||||
break;
|
||||
case 19200:
|
||||
stPortSpeed = B19200;
|
||||
break;
|
||||
case 38400:
|
||||
stPortSpeed = B38400;
|
||||
break;
|
||||
# ifdef B57600
|
||||
case 57600:
|
||||
stPortSpeed = B57600;
|
||||
break;
|
||||
# endif
|
||||
# ifdef B115200
|
||||
case 115200:
|
||||
stPortSpeed = B115200;
|
||||
break;
|
||||
# endif
|
||||
# ifdef B230400
|
||||
case 230400:
|
||||
stPortSpeed = B230400;
|
||||
break;
|
||||
# endif
|
||||
# ifdef B460800
|
||||
case 460800:
|
||||
stPortSpeed = B460800;
|
||||
break;
|
||||
# endif
|
||||
default:
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to set serial port speed to %d bauds. Speed value must be one of those defined in termios(3).",
|
||||
uiPortSpeed);
|
||||
return;
|
||||
};
|
||||
|
||||
// Set port speed (Input and Output)
|
||||
cfsetispeed(&(UART_DATA(sp)->termios_new), stPortSpeed);
|
||||
cfsetospeed(&(UART_DATA(sp)->termios_new), stPortSpeed);
|
||||
if (tcsetattr(UART_DATA(sp)->fd, TCSADRAIN, &(UART_DATA(sp)->termios_new)) == -1) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to apply new speed settings.");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
uart_get_speed(serial_port sp)
|
||||
{
|
||||
uint32_t uiPortSpeed = 0;
|
||||
switch (cfgetispeed(&UART_DATA(sp)->termios_new)) {
|
||||
case B9600:
|
||||
uiPortSpeed = 9600;
|
||||
break;
|
||||
case B19200:
|
||||
uiPortSpeed = 19200;
|
||||
break;
|
||||
case B38400:
|
||||
uiPortSpeed = 38400;
|
||||
break;
|
||||
# ifdef B57600
|
||||
case B57600:
|
||||
uiPortSpeed = 57600;
|
||||
break;
|
||||
# endif
|
||||
# ifdef B115200
|
||||
case B115200:
|
||||
uiPortSpeed = 115200;
|
||||
break;
|
||||
# endif
|
||||
# ifdef B230400
|
||||
case B230400:
|
||||
uiPortSpeed = 230400;
|
||||
break;
|
||||
# endif
|
||||
# ifdef B460800
|
||||
case B460800:
|
||||
uiPortSpeed = 460800;
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
|
||||
return uiPortSpeed;
|
||||
}
|
||||
|
||||
void
|
||||
uart_close_ext(const serial_port sp, const bool restore_termios)
|
||||
{
|
||||
if (UART_DATA(sp)->fd >= 0) {
|
||||
if (restore_termios)
|
||||
tcsetattr(UART_DATA(sp)->fd, TCSANOW, &UART_DATA(sp)->termios_backup);
|
||||
close(UART_DATA(sp)->fd);
|
||||
}
|
||||
free(sp);
|
||||
}
|
||||
|
||||
void
|
||||
uart_close(const serial_port sp)
|
||||
{
|
||||
uart_close_ext(sp, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive data from UART and copy data to \a pbtRx
|
||||
*
|
||||
* @return 0 on success, otherwise driver error code
|
||||
*/
|
||||
int
|
||||
uart_receive(serial_port sp, uint8_t *pbtRx, const size_t szRx, void *abort_p, int timeout)
|
||||
{
|
||||
int iAbortFd = abort_p ? *((int *)abort_p) : 0;
|
||||
int received_bytes_count = 0;
|
||||
int available_bytes_count = 0;
|
||||
const int expected_bytes_count = (int)szRx;
|
||||
int res;
|
||||
fd_set rfds;
|
||||
do {
|
||||
select:
|
||||
// Reset file descriptor
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(UART_DATA(sp)->fd, &rfds);
|
||||
|
||||
if (iAbortFd) {
|
||||
FD_SET(iAbortFd, &rfds);
|
||||
}
|
||||
|
||||
struct timeval timeout_tv;
|
||||
if (timeout > 0) {
|
||||
timeout_tv.tv_sec = (timeout / 1000);
|
||||
timeout_tv.tv_usec = ((timeout % 1000) * 1000);
|
||||
}
|
||||
|
||||
res = select(MAX(UART_DATA(sp)->fd, iAbortFd) + 1, &rfds, NULL, NULL, timeout ? &timeout_tv : NULL);
|
||||
|
||||
if ((res < 0) && (EINTR == errno)) {
|
||||
// The system call was interupted by a signal and a signal handler was
|
||||
// run. Restart the interupted system call.
|
||||
goto select;
|
||||
}
|
||||
|
||||
// Read error
|
||||
if (res < 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Error: %s", strerror(errno));
|
||||
return NFC_EIO;
|
||||
}
|
||||
// Read time-out
|
||||
if (res == 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "Timeout!");
|
||||
return NFC_ETIMEOUT;
|
||||
}
|
||||
|
||||
if (FD_ISSET(iAbortFd, &rfds)) {
|
||||
// Abort requested
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "Abort!");
|
||||
close(iAbortFd);
|
||||
return NFC_EOPABORTED;
|
||||
}
|
||||
|
||||
// Retrieve the count of the incoming bytes
|
||||
res = ioctl(UART_DATA(sp)->fd, FIONREAD, &available_bytes_count);
|
||||
if (res != 0) {
|
||||
return NFC_EIO;
|
||||
}
|
||||
// There is something available, read the data
|
||||
res = read(UART_DATA(sp)->fd, pbtRx + received_bytes_count, MIN(available_bytes_count, (expected_bytes_count - received_bytes_count)));
|
||||
// Stop if the OS has some troubles reading the data
|
||||
if (res <= 0) {
|
||||
return NFC_EIO;
|
||||
}
|
||||
received_bytes_count += res;
|
||||
|
||||
} while (expected_bytes_count > received_bytes_count);
|
||||
LOG_HEX(LOG_GROUP, "RX", pbtRx, szRx);
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send \a pbtTx content to UART
|
||||
*
|
||||
* @return 0 on success, otherwise a driver error is returned
|
||||
*/
|
||||
int
|
||||
uart_send(serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout)
|
||||
{
|
||||
(void) timeout;
|
||||
LOG_HEX(LOG_GROUP, "TX", pbtTx, szTx);
|
||||
if ((int) szTx == write(UART_DATA(sp)->fd, pbtTx, szTx))
|
||||
return NFC_SUCCESS;
|
||||
else
|
||||
return NFC_EIO;
|
||||
}
|
||||
|
||||
char **
|
||||
uart_list_ports(void)
|
||||
{
|
||||
char **res = malloc(sizeof(char *));
|
||||
size_t szRes = 1;
|
||||
|
||||
res[0] = NULL;
|
||||
DIR *dir;
|
||||
if ((dir = opendir("/dev")) == NULL) {
|
||||
perror("opendir error: /dev");
|
||||
return res;
|
||||
}
|
||||
struct dirent entry;
|
||||
struct dirent *result;
|
||||
while ((readdir_r(dir, &entry, &result) == 0) && (result != NULL)) {
|
||||
#if !defined(__APPLE__)
|
||||
if (!isdigit(entry.d_name[strlen(entry.d_name) - 1]))
|
||||
continue;
|
||||
#endif
|
||||
const char **p = serial_ports_device_radix;
|
||||
while (*p) {
|
||||
if (!strncmp(entry.d_name, *p, strlen(*p))) {
|
||||
char **res2 = realloc(res, (szRes + 1) * sizeof(char *));
|
||||
if (!res2) {
|
||||
perror("malloc");
|
||||
goto oom;
|
||||
}
|
||||
res = res2;
|
||||
if (!(res[szRes - 1] = malloc(6 + strlen(entry.d_name)))) {
|
||||
perror("malloc");
|
||||
goto oom;
|
||||
}
|
||||
sprintf(res[szRes - 1], "/dev/%s", entry.d_name);
|
||||
|
||||
szRes++;
|
||||
res[szRes - 1] = NULL;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
oom:
|
||||
closedir(dir);
|
||||
|
||||
return res;
|
||||
}
|
|
@ -67,7 +67,7 @@ nfc_modulation pn53x_ptt_to_nm(const pn53x_target_type ptt);
|
|||
pn53x_modulation pn53x_nm_to_pm(const nfc_modulation nm);
|
||||
pn53x_target_type pn53x_nm_to_ptt(const nfc_modulation nm);
|
||||
|
||||
void pn53x_current_target_new(const struct nfc_device *pnd, const nfc_target *pnt);
|
||||
void *pn53x_current_target_new(const struct nfc_device *pnd, const nfc_target *pnt);
|
||||
void pn53x_current_target_free(const struct nfc_device *pnd);
|
||||
bool pn53x_current_target_is(const struct nfc_device *pnd, const nfc_target *pnt);
|
||||
|
||||
|
@ -1126,7 +1126,10 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd,
|
|||
if ((res = pn53x_decode_target_data(abtTargetsData + 1, szTargetsData - 1, CHIP_DATA(pnd)->type, nm.nmt, &(pnt->nti))) < 0) {
|
||||
return res;
|
||||
}
|
||||
pn53x_current_target_new(pnd, pnt);
|
||||
if (pn53x_current_target_new(pnd, pnt) == NULL) {
|
||||
pnd->last_error = NFC_ESOFT;
|
||||
return pnd->last_error;
|
||||
}
|
||||
}
|
||||
return abtTargetsData[0];
|
||||
}
|
||||
|
@ -1181,7 +1184,9 @@ pn53x_initiator_poll_target(struct nfc_device *pnd,
|
|||
return NFC_ECHIP;
|
||||
break;
|
||||
}
|
||||
pn53x_current_target_new(pnd, pnt);
|
||||
if (pn53x_current_target_new(pnd, pnt) == NULL) {
|
||||
return NFC_ESOFT;
|
||||
}
|
||||
} else {
|
||||
pn53x_set_property_bool(pnd, NP_INFINITE_SELECT, true);
|
||||
// FIXME It does not support DEP targets
|
||||
|
@ -1243,7 +1248,9 @@ pn53x_initiator_select_dep_target(struct nfc_device *pnd,
|
|||
res = pn53x_InJumpForDEP(pnd, ndm, nbr, pbtPassiveInitiatorData, NULL, NULL, 0, pnt, timeout);
|
||||
}
|
||||
if (res >= 0)
|
||||
pn53x_current_target_new(pnd, pnt);
|
||||
if (pn53x_current_target_new(pnd, pnt) == NULL) {
|
||||
return NFC_ESOFT;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1909,7 +1916,10 @@ pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const
|
|||
if (pnt->nm.nmt == NMT_DEP) {
|
||||
pnt->nti.ndi.ndm = ndm; // Update DEP mode
|
||||
}
|
||||
pn53x_current_target_new(pnd, pnt);
|
||||
if (pn53x_current_target_new(pnd, pnt) == NULL) {
|
||||
pnd->last_error = NFC_ESOFT;
|
||||
return pnd->last_error;
|
||||
}
|
||||
|
||||
if (ptm & PTM_ISO14443_4_PICC_ONLY) {
|
||||
// When PN532 is in PICC target mode, it automatically reply to RATS so
|
||||
|
@ -3089,7 +3099,7 @@ pn53x_get_information_about(nfc_device *pnd, char **pbuf)
|
|||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
void *
|
||||
pn53x_current_target_new(const struct nfc_device *pnd, const nfc_target *pnt)
|
||||
{
|
||||
// Keep the current nfc_target for further commands
|
||||
|
@ -3097,7 +3107,11 @@ pn53x_current_target_new(const struct nfc_device *pnd, const nfc_target *pnt)
|
|||
free(CHIP_DATA(pnd)->current_target);
|
||||
}
|
||||
CHIP_DATA(pnd)->current_target = malloc(sizeof(nfc_target));
|
||||
if (!CHIP_DATA(pnd)->current_target) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(CHIP_DATA(pnd)->current_target, pnt, sizeof(nfc_target));
|
||||
return CHIP_DATA(pnd)->current_target;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3122,11 +3136,13 @@ pn53x_current_target_is(const struct nfc_device *pnd, const nfc_target *pnt)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
void *
|
||||
pn53x_data_new(struct nfc_device *pnd, const struct pn53x_io *io)
|
||||
{
|
||||
pnd->chip_data = malloc(sizeof(struct pn53x_data));
|
||||
|
||||
if (!pnd->chip_data) {
|
||||
return NULL;
|
||||
}
|
||||
// Keep I/O functions
|
||||
CHIP_DATA(pnd)->io = io;
|
||||
|
||||
|
@ -3165,6 +3181,8 @@ pn53x_data_new(struct nfc_device *pnd, const struct pn53x_io *io)
|
|||
CHIP_DATA(pnd)->supported_modulation_as_initiator = NULL;
|
||||
|
||||
CHIP_DATA(pnd)->supported_modulation_as_target = NULL;
|
||||
|
||||
return pnd->chip_data;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -394,7 +394,7 @@ int pn53x_get_supported_modulation(nfc_device *pnd, const nfc_mode mode, cons
|
|||
int pn53x_get_supported_baud_rate(nfc_device *pnd, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br);
|
||||
int pn53x_get_information_about(nfc_device *pnd, char **pbuf);
|
||||
|
||||
void pn53x_data_new(struct nfc_device *pnd, const struct pn53x_io *io);
|
||||
void *pn53x_data_new(struct nfc_device *pnd, const struct pn53x_io *io);
|
||||
void pn53x_data_free(struct nfc_device *pnd);
|
||||
|
||||
#endif // __NFC_CHIPS_PN53X_H__
|
||||
|
|
|
@ -68,6 +68,7 @@ conf_parse_file(const char *filename, void (*conf_keyvalue)(void *data, const ch
|
|||
regex_t preg;
|
||||
if (regcomp(&preg, str_regex, REG_EXTENDED | REG_NOTEOL) != 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Regular expression used for configuration file parsing is not valid.");
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
size_t nmatch = preg.re_nsub + 1;
|
||||
|
@ -75,6 +76,7 @@ conf_parse_file(const char *filename, void (*conf_keyvalue)(void *data, const ch
|
|||
if (!pmatch) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Not enough memory: malloc failed.");
|
||||
regfree(&preg);
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -108,6 +110,7 @@ conf_parse_file(const char *filename, void (*conf_keyvalue)(void *data, const ch
|
|||
|
||||
free(pmatch);
|
||||
regfree(&preg);
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -264,7 +264,10 @@ acr122_pcsc_open(const nfc_context *context, const nfc_connstring connstring)
|
|||
}
|
||||
|
||||
// Alloc and init chip's data
|
||||
pn53x_data_new(pnd, &acr122_pcsc_io);
|
||||
if (pn53x_data_new(pnd, &acr122_pcsc_io) == NULL) {
|
||||
perror("malloc");
|
||||
goto error;
|
||||
}
|
||||
|
||||
SCARDCONTEXT *pscc;
|
||||
|
||||
|
|
|
@ -452,7 +452,10 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring)
|
|||
*DRIVER_DATA(pnd) = data;
|
||||
|
||||
// Alloc and init chip's data
|
||||
pn53x_data_new(pnd, &acr122_usb_io);
|
||||
if (pn53x_data_new(pnd, &acr122_usb_io) == NULL) {
|
||||
perror("malloc");
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy(&(DRIVER_DATA(pnd)->tama_frame), acr122_usb_frame_template, sizeof(acr122_usb_frame_template));
|
||||
memcpy(&(DRIVER_DATA(pnd)->apdu_frame), acr122_usb_frame_template, sizeof(acr122_usb_frame_template));
|
||||
|
|
|
@ -429,6 +429,7 @@ acr122s_scan(const nfc_context *context, nfc_connstring connstrings[], const siz
|
|||
nfc_device *pnd = nfc_device_new(context, connstring);
|
||||
if (!pnd) {
|
||||
perror("malloc");
|
||||
uart_close(sp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -436,6 +437,8 @@ acr122s_scan(const nfc_context *context, nfc_connstring connstrings[], const siz
|
|||
pnd->driver_data = malloc(sizeof(struct acr122s_data));
|
||||
if (!pnd->driver_data) {
|
||||
perror("malloc");
|
||||
uart_close(sp);
|
||||
nfc_device_free(pnd);
|
||||
return -1;
|
||||
}
|
||||
DRIVER_DATA(pnd)->port = sp;
|
||||
|
@ -443,13 +446,20 @@ acr122s_scan(const nfc_context *context, nfc_connstring connstrings[], const siz
|
|||
|
||||
#ifndef WIN32
|
||||
if (pipe(DRIVER_DATA(pnd)->abort_fds) < 0) {
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
nfc_device_free(pnd);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
DRIVER_DATA(pnd)->abort_flag = false;
|
||||
#endif
|
||||
|
||||
pn53x_data_new(pnd, &acr122s_io);
|
||||
if (pn53x_data_new(pnd, &acr122s_io) == NULL) {
|
||||
perror("malloc");
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
nfc_device_free(pnd);
|
||||
return 0;
|
||||
}
|
||||
CHIP_DATA(pnd)->type = PN532;
|
||||
CHIP_DATA(pnd)->power_mode = NORMAL;
|
||||
|
||||
|
@ -459,9 +469,9 @@ acr122s_scan(const nfc_context *context, nfc_connstring connstrings[], const siz
|
|||
ret = -1;
|
||||
}
|
||||
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
nfc_device_free(pnd);
|
||||
uart_close(sp);
|
||||
|
||||
if (ret != 0)
|
||||
continue;
|
||||
|
@ -497,7 +507,6 @@ acr122s_close(nfc_device *pnd)
|
|||
close(DRIVER_DATA(pnd)->abort_fds[1]);
|
||||
#endif
|
||||
|
||||
free(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
nfc_device_free(pnd);
|
||||
}
|
||||
|
@ -550,16 +559,19 @@ acr122s_open(const nfc_context *context, const nfc_connstring connstring)
|
|||
pnd = nfc_device_new(context, connstring);
|
||||
if (!pnd) {
|
||||
perror("malloc");
|
||||
acr122s_close(pnd);
|
||||
free(ndd.port);
|
||||
uart_close(sp);
|
||||
return NULL;
|
||||
}
|
||||
pnd->driver = &acr122s_driver;
|
||||
strcpy(pnd->name, ACR122S_DRIVER_NAME);
|
||||
free(ndd.port);
|
||||
|
||||
pnd->driver_data = malloc(sizeof(struct acr122s_data));
|
||||
if (!pnd->driver_data) {
|
||||
perror("malloc");
|
||||
acr122s_close(pnd);
|
||||
uart_close(sp);
|
||||
nfc_device_free(pnd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -568,14 +580,20 @@ acr122s_open(const nfc_context *context, const nfc_connstring connstring)
|
|||
|
||||
#ifndef WIN32
|
||||
if (pipe(DRIVER_DATA(pnd)->abort_fds) < 0) {
|
||||
acr122s_close(pnd);
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
nfc_device_free(pnd);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
DRIVER_DATA(pnd)->abort_flag = false;
|
||||
#endif
|
||||
|
||||
pn53x_data_new(pnd, &acr122s_io);
|
||||
if (pn53x_data_new(pnd, &acr122s_io) == NULL) {
|
||||
perror("malloc");
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
nfc_device_free(pnd);
|
||||
return NULL;
|
||||
}
|
||||
CHIP_DATA(pnd)->type = PN532;
|
||||
|
||||
#if 1
|
||||
|
|
|
@ -120,6 +120,7 @@ arygon_scan(const nfc_context *context, nfc_connstring connstrings[], const size
|
|||
nfc_device *pnd = nfc_device_new(context, connstring);
|
||||
if (!pnd) {
|
||||
perror("malloc");
|
||||
uart_close(sp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -127,16 +128,26 @@ arygon_scan(const nfc_context *context, nfc_connstring connstrings[], const size
|
|||
pnd->driver_data = malloc(sizeof(struct arygon_data));
|
||||
if (!pnd->driver_data) {
|
||||
perror("malloc");
|
||||
uart_close(sp);
|
||||
nfc_device_free(pnd);
|
||||
return 0;
|
||||
}
|
||||
DRIVER_DATA(pnd)->port = sp;
|
||||
|
||||
// Alloc and init chip's data
|
||||
pn53x_data_new(pnd, &arygon_tama_io);
|
||||
if (pn53x_data_new(pnd, &arygon_tama_io) == NULL) {
|
||||
perror("malloc");
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
nfc_device_free(pnd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
// pipe-based abort mecanism
|
||||
if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
nfc_device_free(pnd);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
@ -144,9 +155,9 @@ arygon_scan(const nfc_context *context, nfc_connstring connstrings[], const size
|
|||
#endif
|
||||
|
||||
int res = arygon_reset_tama(pnd);
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
nfc_device_free(pnd);
|
||||
uart_close(sp);
|
||||
if (res < 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -187,7 +198,6 @@ arygon_close(nfc_device *pnd)
|
|||
close(DRIVER_DATA(pnd)->iAbortFds[1]);
|
||||
#endif
|
||||
|
||||
free(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
nfc_device_free(pnd);
|
||||
}
|
||||
|
@ -238,20 +248,28 @@ arygon_open(const nfc_context *context, const nfc_connstring connstring)
|
|||
if (!pnd) {
|
||||
perror("malloc");
|
||||
free(ndd.port);
|
||||
uart_close(sp);
|
||||
return NULL;
|
||||
}
|
||||
snprintf(pnd->name, sizeof(pnd->name), "%s:%s", ARYGON_DRIVER_NAME, ndd.port);
|
||||
free(ndd.port);
|
||||
|
||||
pnd->driver_data = malloc(sizeof(struct arygon_data));
|
||||
if (!pnd->driver_data) {
|
||||
perror("malloc");
|
||||
free(ndd.port);
|
||||
uart_close(sp);
|
||||
nfc_device_free(pnd);
|
||||
return NULL;
|
||||
}
|
||||
DRIVER_DATA(pnd)->port = sp;
|
||||
|
||||
// Alloc and init chip's data
|
||||
pn53x_data_new(pnd, &arygon_tama_io);
|
||||
if (pn53x_data_new(pnd, &arygon_tama_io) == NULL) {
|
||||
perror("malloc");
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
nfc_device_free(pnd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// The PN53x chip opened to ARYGON MCU doesn't seems to be in LowVBat mode
|
||||
CHIP_DATA(pnd)->power_mode = NORMAL;
|
||||
|
@ -263,7 +281,9 @@ arygon_open(const nfc_context *context, const nfc_connstring connstring)
|
|||
#ifndef WIN32
|
||||
// pipe-based abort mecanism
|
||||
if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
|
||||
free(ndd.port);
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
nfc_device_free(pnd);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -90,18 +90,26 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
|
|||
nfc_device *pnd = nfc_device_new(context, connstring);
|
||||
if (!pnd) {
|
||||
perror("malloc");
|
||||
uart_close(sp);
|
||||
return 0;
|
||||
}
|
||||
pnd->driver = &pn532_uart_driver;
|
||||
pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
|
||||
if (!pnd->driver_data) {
|
||||
perror("malloc");
|
||||
uart_close(sp);
|
||||
nfc_device_free(pnd);
|
||||
return 0;
|
||||
}
|
||||
DRIVER_DATA(pnd)->port = sp;
|
||||
|
||||
// Alloc and init chip's data
|
||||
pn53x_data_new(pnd, &pn532_uart_io);
|
||||
if (pn53x_data_new(pnd, &pn532_uart_io) == NULL) {
|
||||
perror("malloc");
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
nfc_device_free(pnd);
|
||||
return 0;
|
||||
}
|
||||
// SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532
|
||||
CHIP_DATA(pnd)->type = PN532;
|
||||
// This device starts in LowVBat power mode
|
||||
|
@ -110,6 +118,9 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
|
|||
#ifndef WIN32
|
||||
// pipe-based abort mecanism
|
||||
if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
nfc_device_free(pnd);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
@ -118,9 +129,9 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
|
|||
|
||||
// Check communication using "Diagnose" command, with "Communication test" (0x00)
|
||||
int res = pn53x_check_communication(pnd);
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
nfc_device_free(pnd);
|
||||
uart_close(sp);
|
||||
if (res < 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -160,7 +171,6 @@ pn532_uart_close(nfc_device *pnd)
|
|||
close(DRIVER_DATA(pnd)->iAbortFds[1]);
|
||||
#endif
|
||||
|
||||
free(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
nfc_device_free(pnd);
|
||||
}
|
||||
|
@ -210,20 +220,28 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring)
|
|||
if (!pnd) {
|
||||
perror("malloc");
|
||||
free(ndd.port);
|
||||
uart_close(sp);
|
||||
return NULL;
|
||||
}
|
||||
snprintf(pnd->name, sizeof(pnd->name), "%s:%s", PN532_UART_DRIVER_NAME, ndd.port);
|
||||
free(ndd.port);
|
||||
|
||||
pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
|
||||
if (!pnd->driver_data) {
|
||||
perror("malloc");
|
||||
free(ndd.port);
|
||||
uart_close(sp);
|
||||
nfc_device_free(pnd);
|
||||
return NULL;
|
||||
}
|
||||
DRIVER_DATA(pnd)->port = sp;
|
||||
|
||||
// Alloc and init chip's data
|
||||
pn53x_data_new(pnd, &pn532_uart_io);
|
||||
if (pn53x_data_new(pnd, &pn532_uart_io) == NULL) {
|
||||
perror("malloc");
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
nfc_device_free(pnd);
|
||||
return NULL;
|
||||
}
|
||||
// SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532
|
||||
CHIP_DATA(pnd)->type = PN532;
|
||||
// This device starts in LowVBat mode
|
||||
|
@ -236,7 +254,9 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring)
|
|||
#ifndef WIN32
|
||||
// pipe-based abort mecanism
|
||||
if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) {
|
||||
free(ndd.port);
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
nfc_device_free(pnd);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
|
@ -247,7 +267,6 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring)
|
|||
if (pn53x_check_communication(pnd) < 0) {
|
||||
nfc_perror(pnd, "pn53x_check_communication");
|
||||
pn532_uart_close(pnd);
|
||||
free(ndd.port);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -337,7 +337,10 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring)
|
|||
*DRIVER_DATA(pnd) = data;
|
||||
|
||||
// Alloc and init chip's data
|
||||
pn53x_data_new(pnd, &pn53x_usb_io);
|
||||
if (pn53x_data_new(pnd, &pn53x_usb_io) == NULL) {
|
||||
perror("malloc");
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch (DRIVER_DATA(pnd)->model) {
|
||||
// empirical tuning
|
||||
|
|
31
libnfc/log.c
31
libnfc/log.c
|
@ -32,37 +32,6 @@
|
|||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
/*
|
||||
int
|
||||
log_priority_to_int(const char* priority)
|
||||
{
|
||||
if (strcmp("none", priority) == 0) {
|
||||
return -1;
|
||||
} else if (strcmp("fatal", priority) == 0) {
|
||||
return NFC_LOG_PRIORITY_FATAL;
|
||||
} else if (strcmp("alert", priority) == 0) {
|
||||
return NFC_LOG_PRIORITY_ALERT;
|
||||
} else if (strcmp("critical", priority) == 0) {
|
||||
return NFC_LOG_PRIORITY_CRIT;
|
||||
} else if (strcmp("error", priority) == 0) {
|
||||
return NFC_LOG_PRIORITY_ERROR;
|
||||
} else if (strcmp("warning", priority) == 0) {
|
||||
return NFC_LOG_PRIORITY_WARN;
|
||||
} else if (strcmp("notice", priority) == 0) {
|
||||
return NFC_LOG_PRIORITY_NOTICE;
|
||||
} else if (strcmp("info", priority) == 0) {
|
||||
return NFC_LOG_PRIORITY_INFO;
|
||||
} else if (strcmp("debug", priority) == 0) {
|
||||
return NFC_LOG_PRIORITY_DEBUG;
|
||||
} else if (strcmp("trace", priority) == 0) {
|
||||
return NFC_LOG_PRIORITY_TRACE;
|
||||
}
|
||||
|
||||
// if priority is string is not recognized, we set maximal verbosity
|
||||
return NFC_LOG_PRIORITY_TRACE;
|
||||
}
|
||||
*/
|
||||
|
||||
const char *
|
||||
log_priority_to_str(const int priority)
|
||||
{
|
||||
|
|
|
@ -56,6 +56,7 @@ AC_DEFUN([LIBNFC_ARG_WITH_DRIVERS],
|
|||
DRIVERS_CFLAGS="$DRIVERS_CFLAGS -DDRIVER_ACR122_USB_ENABLED"
|
||||
;;
|
||||
acr122s)
|
||||
uart_required="yes"
|
||||
driver_acr122s_enabled="yes"
|
||||
DRIVERS_CFLAGS="$DRIVERS_CFLAGS -DDRIVER_ACR122S_ENABLED"
|
||||
;;
|
||||
|
@ -65,10 +66,12 @@ AC_DEFUN([LIBNFC_ARG_WITH_DRIVERS],
|
|||
DRIVERS_CFLAGS="$DRIVERS_CFLAGS -DDRIVER_PN53X_USB_ENABLED"
|
||||
;;
|
||||
arygon)
|
||||
uart_required="yes"
|
||||
driver_arygon_enabled="yes"
|
||||
DRIVERS_CFLAGS="$DRIVERS_CFLAGS -DDRIVER_ARYGON_ENABLED"
|
||||
;;
|
||||
pn532_uart)
|
||||
uart_required="yes"
|
||||
driver_pn532_uart_enabled="yes"
|
||||
DRIVERS_CFLAGS="$DRIVERS_CFLAGS -DDRIVER_PN532_UART_ENABLED"
|
||||
;;
|
||||
|
|
|
@ -65,6 +65,7 @@ static mifare_classic_tag mtKeys;
|
|||
static mifare_classic_tag mtDump;
|
||||
static bool bUseKeyA;
|
||||
static bool bUseKeyFile;
|
||||
static bool bForceKeyFile;
|
||||
static bool bTolerateFailures;
|
||||
static uint8_t uiBlocks;
|
||||
static uint8_t keys[] = {
|
||||
|
@ -138,7 +139,7 @@ print_success_or_failure(bool bFailure, uint32_t *uiBlockCounter)
|
|||
{
|
||||
printf("%c", (bFailure) ? 'x' : '.');
|
||||
if (uiBlockCounter && !bFailure)
|
||||
*uiBlockCounter += (*uiBlockCounter < 128) ? 4 : 16;
|
||||
*uiBlockCounter += 1;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -261,6 +262,32 @@ unlock_card(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
get_rats(void)
|
||||
{
|
||||
int res;
|
||||
uint8_t abtRats[2] = { 0xe0, 0x50};
|
||||
// Use raw send/receive methods
|
||||
if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
return -1;
|
||||
}
|
||||
res = nfc_initiator_transceive_bytes(pnd, abtRats, sizeof(abtRats), abtRx, sizeof(abtRx), 0);
|
||||
if (res > 0) {
|
||||
// ISO14443-4 card, turn RF field off/on to access ISO14443-3 again
|
||||
nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, false);
|
||||
nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, true);
|
||||
}
|
||||
// Reselect tag
|
||||
if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
|
||||
printf("Error: tag disappeared\n");
|
||||
nfc_close(pnd);
|
||||
nfc_exit(context);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool
|
||||
read_card(int read_unlocked)
|
||||
{
|
||||
|
@ -419,7 +446,7 @@ static void
|
|||
print_usage(const char *pcProgramName)
|
||||
{
|
||||
printf("Usage: ");
|
||||
printf("%s r|R|w|W a|b <dump.mfd> [<keys.mfd>]\n", pcProgramName);
|
||||
printf("%s r|R|w|W a|b <dump.mfd> [<keys.mfd> [f]]\n", pcProgramName);
|
||||
printf(" r|R|w|W - Perform read from (r) or unlocked read from (R) or write to (w) or unlocked write to (W) card\n");
|
||||
printf(" *** note that unlocked write will attempt to overwrite block 0 including UID\n");
|
||||
printf(" *** unlocked read does not require authentication and will reveal A and B keys\n");
|
||||
|
@ -427,6 +454,7 @@ print_usage(const char *pcProgramName)
|
|||
printf(" a|A|b|B - Use A or B keys for action; Halt on errors (a|b) or tolerate errors (A|B)\n");
|
||||
printf(" <dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
|
||||
printf(" <keys.mfd> - MiFare Dump (MFD) that contain the keys (optional)\n");
|
||||
printf(" f - Force using the keyfile even if UID does not match (optional)\n");
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -464,46 +492,27 @@ main(int argc, const char *argv[])
|
|||
bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
|
||||
bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
|
||||
bUseKeyFile = (argc > 4);
|
||||
bForceKeyFile = ((argc > 5) && (strcmp((char *)argv[5], "f") == 0));
|
||||
}
|
||||
|
||||
if (atAction == ACTION_USAGE) {
|
||||
print_usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// We don't know yet the card size so let's read only the UID from the keyfile for the moment
|
||||
if (bUseKeyFile) {
|
||||
FILE *pfKeys = fopen(argv[4], "rb");
|
||||
if (pfKeys == NULL) {
|
||||
printf("Could not open keys file: %s\n", argv[4]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (fread(&mtKeys, 1, sizeof(mtKeys), pfKeys) != sizeof(mtKeys)) {
|
||||
printf("Could not read keys file: %s\n", argv[4]);
|
||||
if (fread(&mtKeys, 1, 4, pfKeys) != 4) {
|
||||
printf("Could not read UID from key file: %s\n", argv[4]);
|
||||
fclose(pfKeys);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fclose(pfKeys);
|
||||
}
|
||||
|
||||
if (atAction == ACTION_READ) {
|
||||
memset(&mtDump, 0x00, sizeof(mtDump));
|
||||
} else {
|
||||
FILE *pfDump = fopen(argv[3], "rb");
|
||||
|
||||
if (pfDump == NULL) {
|
||||
printf("Could not open dump file: %s\n", argv[3]);
|
||||
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 (context == NULL) {
|
||||
ERR("Unable to init libnfc (malloc)");
|
||||
|
@ -559,6 +568,14 @@ main(int argc, const char *argv[])
|
|||
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("Got card with UID starting as: %02x%02x%02x%02x\n",
|
||||
pbtUID[0], pbtUID[1], pbtUID[2], pbtUID[3]);
|
||||
if (! bForceKeyFile) {
|
||||
printf("Aborting!\n");
|
||||
nfc_close(pnd);
|
||||
nfc_exit(context);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("Found MIFARE Classic card:\n");
|
||||
|
@ -572,11 +589,54 @@ main(int argc, const char *argv[])
|
|||
// 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?
|
||||
// 1K/2K, checked through RATS
|
||||
uiBlocks = 0x3f;
|
||||
// Testing RATS
|
||||
int res;
|
||||
if ((res = get_rats()) > 0) {
|
||||
if ((res >= 10) && (abtRx[5] == 0xc1) && (abtRx[6] == 0x05)
|
||||
&& (abtRx[7] == 0x2f) && (abtRx[8] == 0x2f)
|
||||
&& ((nt.nti.nai.abtAtqa[1] & 0x02) == 0x00)) {
|
||||
// MIFARE Plus 2K
|
||||
uiBlocks = 0x7f;
|
||||
}
|
||||
}
|
||||
printf("Guessing size: seems to be a %i-byte card\n", (uiBlocks + 1) * 16);
|
||||
|
||||
if (bUseKeyFile) {
|
||||
FILE *pfKeys = fopen(argv[4], "rb");
|
||||
if (pfKeys == NULL) {
|
||||
printf("Could not open keys file: %s\n", argv[4]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (fread(&mtKeys, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfKeys) != (uiBlocks + 1) * sizeof(mifare_classic_block)) {
|
||||
printf("Could not read keys file: %s\n", argv[4]);
|
||||
fclose(pfKeys);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fclose(pfKeys);
|
||||
}
|
||||
|
||||
if (atAction == ACTION_READ) {
|
||||
memset(&mtDump, 0x00, sizeof(mtDump));
|
||||
} else {
|
||||
FILE *pfDump = fopen(argv[3], "rb");
|
||||
|
||||
if (pfDump == NULL) {
|
||||
printf("Could not open dump file: %s\n", argv[3]);
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
}
|
||||
|
||||
if (fread(&mtDump, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfDump) != (uiBlocks + 1) * sizeof(mifare_classic_block)) {
|
||||
printf("Could not read dump file: %s\n", argv[3]);
|
||||
fclose(pfDump);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fclose(pfDump);
|
||||
}
|
||||
// printf("Successfully opened required files\n");
|
||||
|
||||
if (atAction == ACTION_READ) {
|
||||
if (read_card(unlock)) {
|
||||
printf("Writing data to file: %s ...", argv[3]);
|
||||
|
@ -588,7 +648,7 @@ main(int argc, const char *argv[])
|
|||
nfc_exit(context);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) {
|
||||
if (fwrite(&mtDump, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfDump) != ((uiBlocks + 1) * sizeof(mifare_classic_block))) {
|
||||
printf("\nCould not write to file: %s\n", argv[3]);
|
||||
fclose(pfDump);
|
||||
nfc_close(pnd);
|
||||
|
|
Loading…
Reference in a new issue