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:
Philippe Teuwen 2013-03-27 11:44:29 +01:00
commit 1417bdc164
29 changed files with 645 additions and 512 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,266 +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_win32.c
* @brief Windows UART driver
*/
#include <inttypes.h>
#include "log.h"
#define LOG_GROUP NFC_LOG_GROUP_COM
#define LOG_CATEGORY "libnfc.bus.uart_win32"
// Handle platform specific includes
#include "contrib/windows.h"
#define delay_ms( X ) Sleep( X )
struct serial_port_windows {
HANDLE hPort; // Serial port handle
DCB dcb; // Device control settings
COMMTIMEOUTS ct; // Serial port time-out configuration
};
serial_port
uart_open(const char *pcPortName)
{
char acPortName[255];
struct serial_port_windows *sp = malloc(sizeof(struct serial_port_windows));
if (sp == 0)
return INVALID_SERIAL_PORT;
// Copy the input "com?" to "\\.\COM?" format
sprintf(acPortName, "\\\\.\\%s", pcPortName);
_strupr(acPortName);
// Try to open the serial port
sp->hPort = CreateFileA(acPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (sp->hPort == INVALID_HANDLE_VALUE) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
// Prepare the device control
memset(&sp->dcb, 0, sizeof(DCB));
sp->dcb.DCBlength = sizeof(DCB);
if (!BuildCommDCBA("baud=9600 data=8 parity=N stop=1", &sp->dcb)) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
// Update the active serial port
if (!SetCommState(sp->hPort, &sp->dcb)) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
sp->ct.ReadIntervalTimeout = 30;
sp->ct.ReadTotalTimeoutMultiplier = 0;
sp->ct.ReadTotalTimeoutConstant = 30;
sp->ct.WriteTotalTimeoutMultiplier = 30;
sp->ct.WriteTotalTimeoutConstant = 0;
if (!SetCommTimeouts(sp->hPort, &sp->ct)) {
uart_close(sp);
return INVALID_SERIAL_PORT;
}
PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
return sp;
}
void
uart_close(const serial_port sp)
{
if (((struct serial_port_windows *) sp)->hPort != INVALID_HANDLE_VALUE) {
CloseHandle(((struct serial_port_windows *) sp)->hPort);
}
free(sp);
}
void
uart_flush_input(const serial_port sp)
{
PurgeComm(((struct serial_port_windows *) sp)->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
}
void
uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
{
struct serial_port_windows *spw;
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Serial port speed requested to be set to %d bauds.", uiPortSpeed);
// Set port speed (Input and Output)
switch (uiPortSpeed) {
case 9600:
case 19200:
case 38400:
case 57600:
case 115200:
case 230400:
case 460800:
break;
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 these constants: 9600 (default), 19200, 38400, 57600, 115200, 230400 or 460800.", uiPortSpeed);
return;
};
spw = (struct serial_port_windows *) sp;
// Set baud rate
spw->dcb.BaudRate = uiPortSpeed;
if (!SetCommState(spw->hPort, &spw->dcb)) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to apply new speed settings.");
return;
}
PurgeComm(spw->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
}
uint32_t
uart_get_speed(const serial_port sp)
{
const struct serial_port_windows *spw = (struct serial_port_windows *) sp;
if (!GetCommState(spw->hPort, (serial_port) & spw->dcb))
return spw->dcb.BaudRate;
return 0;
}
int
uart_receive(serial_port sp, uint8_t *pbtRx, const size_t szRx, void *abort_p, int timeout)
{
DWORD dwBytesToGet = (DWORD)szRx;
DWORD dwBytesReceived = 0;
DWORD dwTotalBytesReceived = 0;
BOOL res;
// XXX Put this part into uart_win32_timeouts () ?
DWORD timeout_ms = timeout;
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = timeout_ms;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = timeout_ms;
if (!SetCommTimeouts(((struct serial_port_windows *) sp)->hPort, &timeouts)) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to apply new timeout settings.");
return NFC_EIO;
}
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Timeouts are set to %lu ms", timeout_ms);
// TODO Enhance the reception method
// - According to MSDN, it could be better to implement nfc_abort_command() mecanism using Cancello()
volatile bool *abort_flag_p = (volatile bool *)abort_p;
do {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "ReadFile");
res = ReadFile(((struct serial_port_windows *) sp)->hPort, pbtRx + dwTotalBytesReceived,
dwBytesToGet,
&dwBytesReceived, NULL);
dwTotalBytesReceived += dwBytesReceived;
if (!res) {
DWORD err = GetLastError();
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "ReadFile error: %lu", err);
return NFC_EIO;
} else if (dwBytesReceived == 0) {
return NFC_ETIMEOUT;
}
if (((DWORD)szRx) > dwTotalBytesReceived) {
dwBytesToGet -= dwBytesReceived;
}
if (abort_flag_p != NULL && (*abort_flag_p) && dwTotalBytesReceived == 0) {
return NFC_EOPABORTED;
}
} while (((DWORD)szRx) > dwTotalBytesReceived);
LOG_HEX(LOG_GROUP, "RX", pbtRx, szRx);
return (dwTotalBytesReceived == (DWORD) szRx) ? 0 : NFC_EIO;
}
int
uart_send(serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout)
{
DWORD dwTxLen = 0;
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = timeout;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = timeout;
if (!SetCommTimeouts(((struct serial_port_windows *) sp)->hPort, &timeouts)) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to apply new timeout settings.");
return NFC_EIO;
}
LOG_HEX(LOG_GROUP, "TX", pbtTx, szTx);
if (!WriteFile(((struct serial_port_windows *) sp)->hPort, pbtTx, szTx, &dwTxLen, NULL)) {
return NFC_EIO;
}
if (!dwTxLen)
return NFC_EIO;
return 0;
}
BOOL is_port_available(int nPort)
{
TCHAR szPort[15];
COMMCONFIG cc;
DWORD dwCCSize;
sprintf(szPort, "COM%d", nPort);
// Check if this port is available
dwCCSize = sizeof(cc);
return GetDefaultCommConfig(szPort, &cc, &dwCCSize);
}
// Path to the serial port is OS-dependant.
// Try to guess what we should use.
#define MAX_SERIAL_PORT_WIN 255
char **
uart_list_ports(void)
{
char **availablePorts = malloc((1 + MAX_SERIAL_PORT_WIN) * sizeof(char *));
int curIndex = 0;
int i;
for (i = 1; i <= MAX_SERIAL_PORT_WIN; i++) {
if (is_port_available(i)) {
availablePorts[curIndex] = (char *)malloc(10);
sprintf(availablePorts[curIndex], "COM%d", i);
// printf("found candidate port: %s\n", availablePorts[curIndex]);
curIndex++;
}
}
availablePorts[curIndex] = NULL;
return availablePorts;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,60 +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:
* 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-internal.h"
#include <stdio.h>
#include <stdarg.h>
#include <strsafe.h>
static 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);
}