Enable aborting blocking commands (e.g. TgInitAsTarget) and refactor
*_check_communication() as pn53x_check_communication().
This commit is contained in:
parent
7ed71a1501
commit
4b6060aeeb
10 changed files with 118 additions and 43 deletions
|
@ -2,6 +2,7 @@
|
|||
* Public platform independent Near Field Communication (NFC) library examples
|
||||
*
|
||||
* Copyright (C) 2010, Romuald Conty
|
||||
* Copyright (C) 2011, Romain Tartiere, Romuald Conty
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -37,6 +38,7 @@
|
|||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <err.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -49,7 +51,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
|
||||
main (int argc, const char *argv[])
|
||||
|
@ -59,6 +70,8 @@ main (int argc, const char *argv[])
|
|||
bool verbose = false;
|
||||
nfc_device_desc_t *pnddDevices;
|
||||
|
||||
signal (SIGINT, stop_polling);
|
||||
|
||||
pnddDevices = parse_args (argc, argv, &szFound, &verbose);
|
||||
|
||||
// Display libnfc version
|
||||
|
|
|
@ -72,6 +72,7 @@ typedef struct {
|
|||
int iLastError;
|
||||
/** Last sent command */
|
||||
int iLastCommand;
|
||||
int iAbortFds[2];
|
||||
} nfc_device_t;
|
||||
// TODO: Move chip's specifics in a chips structure (e.g. iLastCommand, ui8Parameters, ui8TxBits)
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ extern "C" {
|
|||
/* NFC Device/Hardware manipulation */
|
||||
NFC_EXPORT nfc_device_t *nfc_connect (nfc_device_desc_t * pndd);
|
||||
NFC_EXPORT void nfc_disconnect (nfc_device_t * pnd);
|
||||
NFC_EXPORT 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 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 DEINVAL 0x2000 /* Invalid argument */
|
||||
#define DETIMEOUT 0x3000 /* Operation timeout */
|
||||
#define DEABORT 0x4000 /* Operation aborted */
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ void uart_close (const serial_port sp);
|
|||
void uart_set_speed (serial_port sp, const uint32_t uiPortSpeed);
|
||||
uint32_t uart_get_speed (const serial_port sp);
|
||||
|
||||
int uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx);
|
||||
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);
|
||||
|
||||
char **uart_list_ports (void);
|
||||
|
|
|
@ -31,9 +31,10 @@
|
|||
# include <sys/select.h>
|
||||
# include <sys/param.h>
|
||||
# include <ctype.h>
|
||||
# include <termios.h>
|
||||
# include <stdio.h>
|
||||
# include <dirent.h>
|
||||
# include <errno.h>
|
||||
# include <stdio.h>
|
||||
# include <termios.h>
|
||||
|
||||
# include "nfc-internal.h"
|
||||
|
||||
|
@ -215,19 +216,33 @@ static const struct timeval tvTimeout = {
|
|||
* @return 0 on success, otherwise driver error code
|
||||
*/
|
||||
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 *ptv = &tv;
|
||||
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 (((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
|
||||
if (res < 0) {
|
||||
|
@ -239,6 +254,14 @@ uart_receive (serial_port sp, byte_t * pbtRx, const size_t szRx)
|
|||
DBG ("Timeout!");
|
||||
return DETIMEOUT;
|
||||
}
|
||||
|
||||
if (FD_ISSET (iAbortFd, &rfds)) {
|
||||
// Abort requested
|
||||
DBG ("Abort!");
|
||||
close (iAbortFd);
|
||||
return DEABORT;
|
||||
}
|
||||
|
||||
// Retrieve the count of the incoming bytes
|
||||
res = ioctl (((serial_port_unix *) sp)->fd, FIONREAD, &available_bytes_count);
|
||||
if (res != 0) {
|
||||
|
|
|
@ -755,6 +755,7 @@ static struct sErrorMessage {
|
|||
{ DEINVAL, "Invalid argument" },
|
||||
{ DEIO, "Input/output error" },
|
||||
{ DETIMEOUT, "Operation timed-out" },
|
||||
{ DEABORT, "Operation aborted" },
|
||||
{ DENOTSUP, "Operation not supported" }
|
||||
};
|
||||
|
||||
|
@ -1686,3 +1687,16 @@ pn53x_nm_to_ptt(const nfc_modulation_t nm)
|
|||
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))));
|
||||
}
|
||||
|
|
|
@ -210,6 +210,7 @@ bool pn53x_decode_target_data (const byte_t * pbtRawData, size_t szRawData,
|
|||
nfc_target_info_t * pnti);
|
||||
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_check_communication (nfc_device_t *pnd);
|
||||
|
||||
// NFC device as Initiator functions
|
||||
bool pn53x_initiator_select_passive_target (nfc_device_t * pnd,
|
||||
|
|
|
@ -79,7 +79,6 @@ static const byte_t arygon_error_unknown_mode[] = "FF060000\x0d\x0a";
|
|||
// void arygon_ack (const nfc_device_spec_t nds);
|
||||
bool arygon_reset_tama (nfc_device_t * pnd);
|
||||
void arygon_firmware (nfc_device_t * pnd, char * str);
|
||||
bool arygon_check_communication (nfc_device_t * pnd);
|
||||
|
||||
bool
|
||||
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];
|
||||
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) {
|
||||
ERR ("%s", "Unable to read ACK");
|
||||
pnd->iLastError = res;
|
||||
|
@ -235,13 +234,38 @@ arygon_tama_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szDat
|
|||
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
|
||||
arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen)
|
||||
{
|
||||
byte_t abtRxBuf[5];
|
||||
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) {
|
||||
ERR ("%s", "Unable to receive data. (RX)");
|
||||
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])) {
|
||||
// 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");
|
||||
pnd->iLastError = DEISERRFRAME;
|
||||
return -1;
|
||||
|
@ -285,7 +309,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
|
|||
}
|
||||
|
||||
// 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) {
|
||||
ERR ("%s", "Unable to receive data. (RX)");
|
||||
pnd->iLastError = res;
|
||||
|
@ -305,7 +329,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
|
|||
}
|
||||
|
||||
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) {
|
||||
ERR ("%s", "Unable to receive data. (RX)");
|
||||
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) {
|
||||
ERR ("%s", "Unable to receive data. (RX)");
|
||||
pnd->iLastError = res;
|
||||
|
@ -354,7 +378,7 @@ arygon_firmware (nfc_device_t * pnd, char * str)
|
|||
DBG ("Unable to send ARYGON firmware command.");
|
||||
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) {
|
||||
DBG ("Unable to retrieve ARYGON firmware version.");
|
||||
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)
|
||||
// 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) {
|
||||
DBG ("No reply to 'reset TAMA' command.");
|
||||
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))) {
|
||||
// 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));
|
||||
res = uart_receive ((serial_port) nds, abtRx, &szRx);
|
||||
res = uart_receive ((serial_port) nds, abtRx, &szRx, 0);
|
||||
if (res != 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -413,7 +437,7 @@ arygon_ack (const nfc_device_spec_t nds)
|
|||
PRINT_HEX ("TX", arygon_ack_frame, sizeof (arygon_ack_frame));
|
||||
#endif
|
||||
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
|
||||
PRINT_HEX ("RX", abtRx, szRx);
|
||||
#endif
|
||||
|
|
|
@ -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_wakeup (const nfc_device_spec_t nds);
|
||||
bool pn532_uart_check_communication (nfc_device_t *pnd);
|
||||
|
||||
struct pn532_uart_data {
|
||||
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.
|
||||
// TODO pn532_uart_wakeup ((nfc_device_spec_t) sp);
|
||||
// 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.chip_data);
|
||||
uart_close (sp);
|
||||
|
@ -156,7 +155,7 @@ pn532_uart_connect (const nfc_device_desc_t * pndd)
|
|||
pnd->driver = &pn532_uart_driver;
|
||||
|
||||
// Check communication using "Diagnose" command, with "Communication test" (0x00)
|
||||
if (!pn532_uart_check_communication (pnd)) {
|
||||
if (!pn53x_check_communication (pnd)) {
|
||||
pn532_uart_disconnect(pnd);
|
||||
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];
|
||||
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) {
|
||||
ERR ("%s", "Unable to read ACK");
|
||||
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];
|
||||
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) {
|
||||
ERR ("%s", "Unable to receive data. (RX)");
|
||||
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])) {
|
||||
// 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");
|
||||
pnd->iLastError = DEISERRFRAME;
|
||||
return -1;
|
||||
|
@ -269,7 +268,7 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
|
|||
}
|
||||
|
||||
// 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) {
|
||||
ERR ("%s", "Unable to receive data. (RX)");
|
||||
pnd->iLastError = res;
|
||||
|
@ -289,7 +288,7 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
|
|||
}
|
||||
|
||||
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) {
|
||||
ERR ("%s", "Unable to receive data. (RX)");
|
||||
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) {
|
||||
ERR ("%s", "Unable to receive data. (RX)");
|
||||
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));
|
||||
}
|
||||
|
||||
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 = {
|
||||
.name = PN532_UART_DRIVER_NAME,
|
||||
.probe = pn532_uart_probe,
|
||||
|
|
15
libnfc/nfc.c
15
libnfc/nfc.c
|
@ -30,10 +30,12 @@
|
|||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <unistd.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))
|
||||
return NULL;
|
||||
|
||||
pipe (pnd->iAbortFds);
|
||||
|
||||
return pnd;
|
||||
} else {
|
||||
DBG ("No device found using driver: %s", ndr->name);
|
||||
|
@ -160,6 +164,8 @@ nfc_disconnect (nfc_device_t * pnd)
|
|||
nfc_initiator_deselect_target (pnd);
|
||||
// Disable RF field to avoid heating
|
||||
nfc_configure (pnd, NDO_ACTIVATE_FIELD, false);
|
||||
close (pnd->iAbortFds[0]);
|
||||
close (pnd->iAbortFds[1]);
|
||||
// Disconnect, clean up and release the device
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
nfc_abort_command (nfc_device_t * pnd)
|
||||
{
|
||||
if (pnd) {
|
||||
close (pnd->iAbortFds[0]);
|
||||
pipe (pnd->iAbortFds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send bytes and APDU frames
|
||||
* @return Returns \c true if action was successfully performed; otherwise returns \c false.
|
||||
|
|
Loading…
Add table
Reference in a new issue