Enable aborting blocking commands (e.g. TgInitAsTarget) and refactor

*_check_communication() as pn53x_check_communication().
This commit is contained in:
Romain Tartiere 2011-03-04 19:59:49 +00:00
parent 7ed71a1501
commit 4b6060aeeb
10 changed files with 118 additions and 43 deletions

View file

@ -2,6 +2,7 @@
* Public platform independent Near Field Communication (NFC) library examples * Public platform independent Near Field Communication (NFC) library examples
* *
* Copyright (C) 2010, Romuald Conty * Copyright (C) 2010, Romuald Conty
* Copyright (C) 2011, Romain Tartiere, Romuald Conty
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -37,6 +38,7 @@
#endif // HAVE_CONFIG_H #endif // HAVE_CONFIG_H
#include <err.h> #include <err.h>
#include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
@ -49,7 +51,16 @@
#define MAX_DEVICE_COUNT 16 #define MAX_DEVICE_COUNT 16
static nfc_device_t *pnd; static nfc_device_t *pnd = NULL;
void stop_polling (int sig)
{
(void) sig;
if (pnd)
nfc_abort_command (pnd);
else
exit (EXIT_FAILURE);
}
int int
main (int argc, const char *argv[]) main (int argc, const char *argv[])
@ -59,6 +70,8 @@ main (int argc, const char *argv[])
bool verbose = false; bool verbose = false;
nfc_device_desc_t *pnddDevices; nfc_device_desc_t *pnddDevices;
signal (SIGINT, stop_polling);
pnddDevices = parse_args (argc, argv, &szFound, &verbose); pnddDevices = parse_args (argc, argv, &szFound, &verbose);
// Display libnfc version // Display libnfc version

View file

@ -72,6 +72,7 @@ typedef struct {
int iLastError; int iLastError;
/** Last sent command */ /** Last sent command */
int iLastCommand; int iLastCommand;
int iAbortFds[2];
} nfc_device_t; } nfc_device_t;
// TODO: Move chip's specifics in a chips structure (e.g. iLastCommand, ui8Parameters, ui8TxBits) // TODO: Move chip's specifics in a chips structure (e.g. iLastCommand, ui8Parameters, ui8TxBits)

View file

@ -63,6 +63,7 @@ extern "C" {
/* NFC Device/Hardware manipulation */ /* NFC Device/Hardware manipulation */
NFC_EXPORT nfc_device_t *nfc_connect (nfc_device_desc_t * pndd); NFC_EXPORT nfc_device_t *nfc_connect (nfc_device_desc_t * pndd);
NFC_EXPORT void nfc_disconnect (nfc_device_t * pnd); NFC_EXPORT void nfc_disconnect (nfc_device_t * pnd);
NFC_EXPORT void nfc_abort_command (nfc_device_t * pnd);
NFC_EXPORT void nfc_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound); NFC_EXPORT void nfc_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
NFC_EXPORT bool nfc_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable); NFC_EXPORT bool nfc_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
@ -147,6 +148,7 @@ extern "C" {
#define DEIO 0x1000 /* Input/output error */ #define DEIO 0x1000 /* Input/output error */
#define DEINVAL 0x2000 /* Invalid argument */ #define DEINVAL 0x2000 /* Invalid argument */
#define DETIMEOUT 0x3000 /* Operation timeout */ #define DETIMEOUT 0x3000 /* Operation timeout */
#define DEABORT 0x4000 /* Operation aborted */
# ifdef __cplusplus # ifdef __cplusplus
} }

View file

@ -69,7 +69,7 @@ void uart_close (const serial_port sp);
void uart_set_speed (serial_port sp, const uint32_t uiPortSpeed); void uart_set_speed (serial_port sp, const uint32_t uiPortSpeed);
uint32_t uart_get_speed (const serial_port sp); uint32_t uart_get_speed (const serial_port sp);
int uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx); int uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx, int iAbortFd);
int uart_send (serial_port sp, const byte_t * pbtTx, const size_t szTx); int uart_send (serial_port sp, const byte_t * pbtTx, const size_t szTx);
char **uart_list_ports (void); char **uart_list_ports (void);

View file

@ -31,9 +31,10 @@
# include <sys/select.h> # include <sys/select.h>
# include <sys/param.h> # include <sys/param.h>
# include <ctype.h> # include <ctype.h>
# include <termios.h>
# include <stdio.h>
# include <dirent.h> # include <dirent.h>
# include <errno.h>
# include <stdio.h>
# include <termios.h>
# include "nfc-internal.h" # include "nfc-internal.h"
@ -215,19 +216,33 @@ static const struct timeval tvTimeout = {
* @return 0 on success, otherwise driver error code * @return 0 on success, otherwise driver error code
*/ */
int int
uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx) uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx, int iAbortFd)
{ {
struct timeval tv = tvTimeout; struct timeval tv = tvTimeout;
struct timeval *ptv = &tv;
int received_bytes_count = 0; int received_bytes_count = 0;
int available_bytes_count = 0; int available_bytes_count = 0;
const int expected_bytes_count = (int)szRx; const int expected_bytes_count = (int)szRx;
int res; int res;
fd_set rfds; fd_set rfds;
do { do {
select:
// Reset file descriptor // Reset file descriptor
FD_ZERO (&rfds); FD_ZERO (&rfds);
FD_SET (((serial_port_unix *) sp)->fd, &rfds); FD_SET (((serial_port_unix *) sp)->fd, &rfds);
res = select (((serial_port_unix *) sp)->fd + 1, &rfds, NULL, NULL, &tv);
if (iAbortFd) {
FD_SET (iAbortFd, &rfds);
ptv = NULL;
}
res = select (MAX(((serial_port_unix *) sp)->fd, iAbortFd) + 1, &rfds, NULL, NULL, ptv);
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 // Read error
if (res < 0) { if (res < 0) {
@ -239,6 +254,14 @@ uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx)
DBG ("Timeout!"); DBG ("Timeout!");
return DETIMEOUT; return DETIMEOUT;
} }
if (FD_ISSET (iAbortFd, &rfds)) {
// Abort requested
DBG ("Abort!");
close (iAbortFd);
return DEABORT;
}
// Retrieve the count of the incoming bytes // Retrieve the count of the incoming bytes
res = ioctl (((serial_port_unix *) sp)->fd, FIONREAD, &available_bytes_count); res = ioctl (((serial_port_unix *) sp)->fd, FIONREAD, &available_bytes_count);
if (res != 0) { if (res != 0) {

View file

@ -755,6 +755,7 @@ static struct sErrorMessage {
{ DEINVAL, "Invalid argument" }, { DEINVAL, "Invalid argument" },
{ DEIO, "Input/output error" }, { DEIO, "Input/output error" },
{ DETIMEOUT, "Operation timed-out" }, { DETIMEOUT, "Operation timed-out" },
{ DEABORT, "Operation aborted" },
{ DENOTSUP, "Operation not supported" } { DENOTSUP, "Operation not supported" }
}; };
@ -1686,3 +1687,16 @@ pn53x_nm_to_ptt(const nfc_modulation_t nm)
return PTT_UNDEFINED; return PTT_UNDEFINED;
} }
bool
pn53x_check_communication (nfc_device_t *pnd)
{
const byte_t abtCmd[] = { Diagnose, 0x00, 'l', 'i', 'b', 'n', 'f', 'c' };
const byte_t abtExpectedRx[] = { 0x00, 'l', 'i', 'b', 'n', 'f', 'c' };
byte_t abtRx[sizeof(abtExpectedRx)];
size_t szRx = sizeof (abtRx);
if (!pn53x_transceive (pnd, abtCmd, sizeof (abtCmd), abtRx, &szRx))
return false;
return ((sizeof(abtExpectedRx) == szRx) && (0 == memcmp (abtRx, abtExpectedRx, sizeof(abtExpectedRx))));
}

View file

@ -210,6 +210,7 @@ bool pn53x_decode_target_data (const byte_t * pbtRawData, size_t szRawData,
nfc_target_info_t * pnti); nfc_target_info_t * pnti);
bool pn53x_get_firmware_version (nfc_device_t * pnd, char abtFirmwareText[18]); bool pn53x_get_firmware_version (nfc_device_t * pnd, char abtFirmwareText[18]);
bool pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable); bool pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
bool pn53x_check_communication (nfc_device_t *pnd);
// NFC device as Initiator functions // NFC device as Initiator functions
bool pn53x_initiator_select_passive_target (nfc_device_t * pnd, bool pn53x_initiator_select_passive_target (nfc_device_t * pnd,

View file

@ -79,7 +79,6 @@ static const byte_t arygon_error_unknown_mode[] = "FF060000\x0d\x0a";
// void arygon_ack (const nfc_device_spec_t nds); // void arygon_ack (const nfc_device_spec_t nds);
bool arygon_reset_tama (nfc_device_t * pnd); bool arygon_reset_tama (nfc_device_t * pnd);
void arygon_firmware (nfc_device_t * pnd, char * str); void arygon_firmware (nfc_device_t * pnd, char * str);
bool arygon_check_communication (nfc_device_t * pnd);
bool bool
arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound) arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
@ -217,7 +216,7 @@ arygon_tama_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szDat
} }
byte_t abtRxBuf[6]; byte_t abtRxBuf[6];
res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, 6); res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, sizeof (abtRxBuf), 0);
if (res != 0) { if (res != 0) {
ERR ("%s", "Unable to read ACK"); ERR ("%s", "Unable to read ACK");
pnd->iLastError = res; pnd->iLastError = res;
@ -235,13 +234,38 @@ arygon_tama_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szDat
return true; return true;
} }
int
arygon_abort (nfc_device_t *pnd)
{
((struct pn53x_data*)(pnd->chip_data))->state = NORMAL;
// Using Arygon device we can't send ACK frame to abort the running command
return (pn53x_check_communication (pnd)) ? 0 : -1;
}
int int
arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen) arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen)
{ {
byte_t abtRxBuf[5]; byte_t abtRxBuf[5];
size_t len; size_t len;
int abort_fd = 0;
switch (pnd->iLastCommand) {
case InAutoPoll:
case TgInitAsTarget:
case TgGetData:
abort_fd = pnd->iAbortFds[1];
break;
default:
break;
}
int res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, 5, abort_fd);
if (abort_fd && (DEABORT == res)) {
return arygon_abort (pnd);
}
int res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, 5);
if (res != 0) { if (res != 0) {
ERR ("%s", "Unable to receive data. (RX)"); ERR ("%s", "Unable to receive data. (RX)");
pnd->iLastError = res; pnd->iLastError = res;
@ -257,7 +281,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) { if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
// Error frame // Error frame
uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, 3); uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, 3, 0);
ERR ("%s", "Application level error detected"); ERR ("%s", "Application level error detected");
pnd->iLastError = DEISERRFRAME; pnd->iLastError = DEISERRFRAME;
return -1; return -1;
@ -285,7 +309,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
} }
// TFI + PD0 (CC+1) // TFI + PD0 (CC+1)
res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, 2); res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, 2, 0);
if (res != 0) { if (res != 0) {
ERR ("%s", "Unable to receive data. (RX)"); ERR ("%s", "Unable to receive data. (RX)");
pnd->iLastError = res; pnd->iLastError = res;
@ -305,7 +329,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
} }
if (len) { if (len) {
res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, pbtData, len); res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, pbtData, len, 0);
if (res != 0) { if (res != 0) {
ERR ("%s", "Unable to receive data. (RX)"); ERR ("%s", "Unable to receive data. (RX)");
pnd->iLastError = res; pnd->iLastError = res;
@ -313,7 +337,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
} }
} }
res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, 2); res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, 2, 0);
if (res != 0) { if (res != 0) {
ERR ("%s", "Unable to receive data. (RX)"); ERR ("%s", "Unable to receive data. (RX)");
pnd->iLastError = res; pnd->iLastError = res;
@ -354,7 +378,7 @@ arygon_firmware (nfc_device_t * pnd, char * str)
DBG ("Unable to send ARYGON firmware command."); DBG ("Unable to send ARYGON firmware command.");
return; return;
} }
res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRx, szRx); res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRx, szRx, 0);
if (res != 0) { if (res != 0) {
DBG ("Unable to retrieve ARYGON firmware version."); DBG ("Unable to retrieve ARYGON firmware version.");
return; return;
@ -381,7 +405,7 @@ arygon_reset_tama (nfc_device_t * pnd)
// Two reply are possible from ARYGON device: arygon_error_none (ie. in case the byte is well-sent) // Two reply are possible from ARYGON device: arygon_error_none (ie. in case the byte is well-sent)
// or arygon_error_unknown_mode (ie. in case of the first byte was bad-transmitted) // or arygon_error_unknown_mode (ie. in case of the first byte was bad-transmitted)
res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRx, szRx); res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRx, szRx, 0);
if (res != 0) { if (res != 0) {
DBG ("No reply to 'reset TAMA' command."); DBG ("No reply to 'reset TAMA' command.");
return false; return false;
@ -390,7 +414,7 @@ arygon_reset_tama (nfc_device_t * pnd)
if ( 0 == memcmp (abtRx, arygon_error_unknown_mode, sizeof (arygon_error_unknown_mode))) { if ( 0 == memcmp (abtRx, arygon_error_unknown_mode, sizeof (arygon_error_unknown_mode))) {
// HACK Here we are... the first byte wasn't sent as expected, so we resend the same command // HACK Here we are... the first byte wasn't sent as expected, so we resend the same command
uart_send ((serial_port) nds, arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd)); uart_send ((serial_port) nds, arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd));
res = uart_receive ((serial_port) nds, abtRx, &szRx); res = uart_receive ((serial_port) nds, abtRx, &szRx, 0);
if (res != 0) { if (res != 0) {
return false; return false;
} }
@ -413,7 +437,7 @@ arygon_ack (const nfc_device_spec_t nds)
PRINT_HEX ("TX", arygon_ack_frame, sizeof (arygon_ack_frame)); PRINT_HEX ("TX", arygon_ack_frame, sizeof (arygon_ack_frame));
#endif #endif
uart_send ((serial_port) nds, arygon_ack_frame, sizeof (arygon_ack_frame)); uart_send ((serial_port) nds, arygon_ack_frame, sizeof (arygon_ack_frame));
uart_receive ((serial_port) nds, abtRx, &szRx); uart_receive ((serial_port) nds, abtRx, &szRx, 0);
#ifdef DEBUG #ifdef DEBUG
PRINT_HEX ("RX", abtRx, szRx); PRINT_HEX ("RX", abtRx, szRx);
#endif #endif

View file

@ -50,7 +50,6 @@ static const byte_t ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
void pn532_uart_ack (nfc_device_t * pnd); void pn532_uart_ack (nfc_device_t * pnd);
// void pn532_uart_wakeup (const nfc_device_spec_t nds); // void pn532_uart_wakeup (const nfc_device_spec_t nds);
bool pn532_uart_check_communication (nfc_device_t *pnd);
struct pn532_uart_data { struct pn532_uart_data {
serial_port port; serial_port port;
@ -95,7 +94,7 @@ pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps
// PN532 could be powered down, we need to wake it up before line testing. // PN532 could be powered down, we need to wake it up before line testing.
// TODO pn532_uart_wakeup ((nfc_device_spec_t) sp); // TODO pn532_uart_wakeup ((nfc_device_spec_t) sp);
// Check communication using "Diagnose" command, with "Communication test" (0x00) // Check communication using "Diagnose" command, with "Communication test" (0x00)
bool res = pn532_uart_check_communication (&nd); bool res = pn53x_check_communication (&nd);
free(nd.driver_data); free(nd.driver_data);
free(nd.chip_data); free(nd.chip_data);
uart_close (sp); uart_close (sp);
@ -156,7 +155,7 @@ pn532_uart_connect (const nfc_device_desc_t * pndd)
pnd->driver = &pn532_uart_driver; pnd->driver = &pn532_uart_driver;
// Check communication using "Diagnose" command, with "Communication test" (0x00) // Check communication using "Diagnose" command, with "Communication test" (0x00)
if (!pn532_uart_check_communication (pnd)) { if (!pn53x_check_communication (pnd)) {
pn532_uart_disconnect(pnd); pn532_uart_disconnect(pnd);
return NULL; return NULL;
} }
@ -204,7 +203,7 @@ pn532_uart_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData
} }
byte_t abtRxBuf[6]; byte_t abtRxBuf[6];
res = uart_receive (((struct pn532_uart_data*)(pnd->driver_data))->port, abtRxBuf, 6); res = uart_receive (((struct pn532_uart_data*)(pnd->driver_data))->port, abtRxBuf, 6, 0);
if (res != 0) { if (res != 0) {
ERR ("%s", "Unable to read ACK"); ERR ("%s", "Unable to read ACK");
pnd->iLastError = res; pnd->iLastError = res;
@ -225,7 +224,7 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
byte_t abtRxBuf[5]; byte_t abtRxBuf[5];
size_t len; size_t len;
int res = uart_receive (((struct pn532_uart_data*)(pnd->driver_data))->port, abtRxBuf, 5); int res = uart_receive (((struct pn532_uart_data*)(pnd->driver_data))->port, abtRxBuf, 5, 0);
if (res != 0) { if (res != 0) {
ERR ("%s", "Unable to receive data. (RX)"); ERR ("%s", "Unable to receive data. (RX)");
pnd->iLastError = res; pnd->iLastError = res;
@ -241,7 +240,7 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) { if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
// Error frame // Error frame
uart_receive (((struct pn532_uart_data*)(pnd->driver_data))->port, abtRxBuf, 3); uart_receive (((struct pn532_uart_data*)(pnd->driver_data))->port, abtRxBuf, 3, 0);
ERR ("%s", "Application level error detected"); ERR ("%s", "Application level error detected");
pnd->iLastError = DEISERRFRAME; pnd->iLastError = DEISERRFRAME;
return -1; return -1;
@ -269,7 +268,7 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
} }
// TFI + PD0 (CC+1) // TFI + PD0 (CC+1)
res = uart_receive (((struct pn532_uart_data*)(pnd->driver_data))->port, abtRxBuf, 2); res = uart_receive (((struct pn532_uart_data*)(pnd->driver_data))->port, abtRxBuf, 2, 0);
if (res != 0) { if (res != 0) {
ERR ("%s", "Unable to receive data. (RX)"); ERR ("%s", "Unable to receive data. (RX)");
pnd->iLastError = res; pnd->iLastError = res;
@ -289,7 +288,7 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
} }
if (len) { if (len) {
res = uart_receive (((struct pn532_uart_data*)(pnd->driver_data))->port, pbtData, len); res = uart_receive (((struct pn532_uart_data*)(pnd->driver_data))->port, pbtData, len, 0);
if (res != 0) { if (res != 0) {
ERR ("%s", "Unable to receive data. (RX)"); ERR ("%s", "Unable to receive data. (RX)");
pnd->iLastError = res; pnd->iLastError = res;
@ -297,7 +296,7 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
} }
} }
res = uart_receive (((struct pn532_uart_data*)(pnd->driver_data))->port, abtRxBuf, 2); res = uart_receive (((struct pn532_uart_data*)(pnd->driver_data))->port, abtRxBuf, 2, 0);
if (res != 0) { if (res != 0) {
ERR ("%s", "Unable to receive data. (RX)"); ERR ("%s", "Unable to receive data. (RX)");
pnd->iLastError = res; pnd->iLastError = res;
@ -331,23 +330,6 @@ pn532_uart_ack (nfc_device_t * pnd)
uart_send (((struct pn532_uart_data*)(pnd->driver_data))->port, ack_frame, sizeof (ack_frame)); uart_send (((struct pn532_uart_data*)(pnd->driver_data))->port, ack_frame, sizeof (ack_frame));
} }
bool
pn532_uart_check_communication (nfc_device_t *pnd)
{
const byte_t abtMsg[] = { Diagnose, 0x00, 'l', 'i', 'b', 'n', 'f', 'c' };
if (!pn532_uart_send (pnd, abtMsg, sizeof (abtMsg)))
return false;
const byte_t abtExpectedRes[] = { 0x00, 'l', 'i', 'b', 'n', 'f', 'c' };
byte_t abtRes[sizeof(abtExpectedRes)];
int res;
if ((res = pn532_uart_receive (pnd, abtRes, sizeof(abtRes))) < 0)
return false;
return ((sizeof(abtRes) == res) && (0 == memcmp (abtRes, abtExpectedRes, sizeof(abtExpectedRes))));
}
const struct nfc_driver_t pn532_uart_driver = { const struct nfc_driver_t pn532_uart_driver = {
.name = PN532_UART_DRIVER_NAME, .name = PN532_UART_DRIVER_NAME,
.probe = pn532_uart_probe, .probe = pn532_uart_probe,

View file

@ -30,10 +30,12 @@
# include "config.h" # include "config.h"
#endif // HAVE_CONFIG_H #endif // HAVE_CONFIG_H
#include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <nfc/nfc.h> #include <nfc/nfc.h>
@ -136,6 +138,8 @@ nfc_connect (nfc_device_desc_t * pndd)
if (!nfc_configure (pnd, NDO_ACCEPT_MULTIPLE_FRAMES, false)) if (!nfc_configure (pnd, NDO_ACCEPT_MULTIPLE_FRAMES, false))
return NULL; return NULL;
pipe (pnd->iAbortFds);
return pnd; return pnd;
} else { } else {
DBG ("No device found using driver: %s", ndr->name); DBG ("No device found using driver: %s", ndr->name);
@ -160,6 +164,8 @@ nfc_disconnect (nfc_device_t * pnd)
nfc_initiator_deselect_target (pnd); nfc_initiator_deselect_target (pnd);
// Disable RF field to avoid heating // Disable RF field to avoid heating
nfc_configure (pnd, NDO_ACTIVATE_FIELD, false); nfc_configure (pnd, NDO_ACTIVATE_FIELD, false);
close (pnd->iAbortFds[0]);
close (pnd->iAbortFds[1]);
// Disconnect, clean up and release the device // Disconnect, clean up and release the device
pnd->driver->disconnect (pnd); pnd->driver->disconnect (pnd);
} }
@ -584,6 +590,15 @@ nfc_target_init (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t
return pn53x_target_init (pnd, pnt, pbtRx, pszRx); return pn53x_target_init (pnd, pnt, pbtRx, pszRx);
} }
void
nfc_abort_command (nfc_device_t * pnd)
{
if (pnd) {
close (pnd->iAbortFds[0]);
pipe (pnd->iAbortFds);
}
}
/** /**
* @brief Send bytes and APDU frames * @brief Send bytes and APDU frames
* @return Returns \c true if action was successfully performed; otherwise returns \c false. * @return Returns \c true if action was successfully performed; otherwise returns \c false.