Allow to connect to a device using a connection string:

- Provide a nfc_get_default_device() that allow to grab the connstring stored
   in LIBNFC_DEFAULT_DEVICE environnement variable or returns the first
   available device if not set;
 - nfc_connect(NULL) now takes the default device (see
   nfc_get_default_device());
 - Removes nfc_driver_desc_t from public types
 - Defines nfc_connstring as char[1024]
 - examples/*: use nfc_connstring
 - examples/nfc-poll: now uses only the default device (instead of all devices
   availables)
 - Removes parse_args() from nfc-utils.[hc]
This commit is contained in:
Romuald Conty 2011-10-17 13:03:56 +00:00
parent dc842a844c
commit 55daa29a7c
20 changed files with 559 additions and 380 deletions

View file

@ -66,16 +66,16 @@ main (int argc, const char *argv[])
size_t szDeviceFound; size_t szDeviceFound;
byte_t abtTx[] = "Hello Mars!"; byte_t abtTx[] = "Hello Mars!";
#define MAX_DEVICE_COUNT 2 #define MAX_DEVICE_COUNT 2
nfc_device_desc_t pnddDevices[MAX_DEVICE_COUNT]; nfc_connstring connstrings[MAX_DEVICE_COUNT];
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szDeviceFound); nfc_list_devices (connstrings, MAX_DEVICE_COUNT, &szDeviceFound);
// Little hack to allow using nfc-dep-initiator & nfc-dep-target from // Little hack to allow using nfc-dep-initiator & nfc-dep-target from
// the same machine: if there is more than one readers connected // the same machine: if there is more than one readers connected
// nfc-dep-target will connect to the second reader // nfc-dep-target will connect to the second reader
// (we hope they're always detected in the same order) // (we hope they're always detected in the same order)
if (szDeviceFound == 1) { if (szDeviceFound == 1) {
pnd = nfc_connect (&(pnddDevices[0])); pnd = nfc_connect (connstrings[0]);
} else if (szDeviceFound > 1) { } else if (szDeviceFound > 1) {
pnd = nfc_connect (&(pnddDevices[1])); pnd = nfc_connect (connstrings[1]);
} else { } else {
printf("No device found."); printf("No device found.");
return EXIT_FAILURE; return EXIT_FAILURE;

View file

@ -65,15 +65,10 @@ void stop_polling (int sig)
int int
main (int argc, const char *argv[]) main (int argc, const char *argv[])
{ {
size_t szFound;
size_t i;
bool verbose = false; bool verbose = false;
nfc_device_desc_t *pnddDevices;
signal (SIGINT, stop_polling); signal (SIGINT, stop_polling);
pnddDevices = parse_args (argc, argv, &szFound, &verbose);
// Display libnfc version // Display libnfc version
const char *acLibnfcVersion = nfc_version (); const char *acLibnfcVersion = nfc_version ();
@ -83,59 +78,43 @@ main (int argc, const char *argv[])
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion); printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
if (szFound == 0) { const uint8_t uiPollNr = 20;
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) { const uint8_t uiPeriod = 2;
fprintf (stderr, "malloc() failed\n"); const nfc_modulation_t nmModulations[5] = {
exit (EXIT_FAILURE); { .nmt = NMT_ISO14443A, .nbr = NBR_106 },
} { .nmt = NMT_ISO14443B, .nbr = NBR_106 },
{ .nmt = NMT_FELICA, .nbr = NBR_212 },
{ .nmt = NMT_FELICA, .nbr = NBR_424 },
{ .nmt = NMT_JEWEL, .nbr = NBR_106 },
};
const size_t szModulations = 5;
nfc_target_t nt;
bool res;
pnd = nfc_connect (NULL);
if (pnd == NULL) {
ERR ("%s", "Unable to connect to NFC device.");
exit (EXIT_FAILURE);
} }
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound); nfc_initiator_init (pnd);
if (szFound == 0) { printf ("Connected to NFC reader: %s\n", pnd->acName);
printf ("No NFC device found.\n"); printf ("NFC device will poll during %ld ms (%u pollings of %lu ms for %zd modulations)\n", (unsigned long) uiPollNr * szModulations * uiPeriod * 150, uiPollNr, (unsigned long) uiPeriod * 150, szModulations);
} res = nfc_initiator_poll_target (pnd, nmModulations, szModulations, uiPollNr, uiPeriod, &nt);
if (res) {
for (i = 0; i < szFound; i++) { print_nfc_target ( nt, verbose );
const uint8_t uiPollNr = 20; } else {
const uint8_t uiPeriod = 2; if (pnd->iLastError) {
const nfc_modulation_t nmModulations[5] = { nfc_perror (pnd, "nfc_initiator_poll_targets");
{ .nmt = NMT_ISO14443A, .nbr = NBR_106 }, nfc_disconnect (pnd);
{ .nmt = NMT_ISO14443B, .nbr = NBR_106 },
{ .nmt = NMT_FELICA, .nbr = NBR_212 },
{ .nmt = NMT_FELICA, .nbr = NBR_424 },
{ .nmt = NMT_JEWEL, .nbr = NBR_106 },
};
const size_t szModulations = 5;
nfc_target_t nt;
bool res;
pnd = nfc_connect (&(pnddDevices[i]));
if (pnd == NULL) {
ERR ("%s", "Unable to connect to NFC device.");
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
}
nfc_initiator_init (pnd);
printf ("Connected to NFC reader: %s\n", pnd->acName);
printf ("NFC device will poll during %ld ms (%u pollings of %lu ms for %zd modulations)\n", (unsigned long) uiPollNr * szModulations * uiPeriod * 150, uiPollNr, (unsigned long) uiPeriod * 150, szModulations);
res = nfc_initiator_poll_target (pnd, nmModulations, szModulations, uiPollNr, uiPeriod, &nt);
if (res) {
print_nfc_target ( nt, verbose );
} else { } else {
if (pnd->iLastError) { printf ("No target found.\n");
nfc_perror (pnd, "nfc_initiator_poll_targets");
nfc_disconnect (pnd);
exit (EXIT_FAILURE);
} else {
printf ("No target found.\n");
}
} }
nfc_disconnect (pnd);
} }
nfc_disconnect (pnd);
free (pnddDevices);
exit (EXIT_SUCCESS); exit (EXIT_SUCCESS);
} }

View file

@ -83,7 +83,6 @@ main (int argc, char *argv[])
int arg; int arg;
bool quiet_output = false; bool quiet_output = false;
size_t szFound; size_t szFound;
nfc_device_desc_t *pnddDevices;
const char *acLibnfcVersion = nfc_version (); const char *acLibnfcVersion = nfc_version ();
// Get commandline options // Get commandline options
@ -109,20 +108,16 @@ main (int argc, char *argv[])
signal (SIGINT, (void (*)()) intr_hdlr); signal (SIGINT, (void (*)()) intr_hdlr);
#endif #endif
// Allocate memory to put the result of available devices listing nfc_connstring connstrings[MAX_DEVICE_COUNT];
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
fprintf (stderr, "malloc() failed\n");
return EXIT_FAILURE;
}
// List available devices // List available devices
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound); nfc_list_devices (connstrings, MAX_DEVICE_COUNT, &szFound);
if (szFound < 2) { if (szFound < 2) {
ERR ("%zd device found but two connected devices are needed to relay NFC.", szFound); ERR ("%zd device found but two connected devices are needed to relay NFC.", szFound);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// Try to open the NFC emulator device // Try to open the NFC emulator device
pndTag = nfc_connect (&(pnddDevices[0])); pndTag = nfc_connect (connstrings[0]);
if (pndTag == NULL) { if (pndTag == NULL) {
printf ("Error connecting NFC emulator device\n"); printf ("Error connecting NFC emulator device\n");
return EXIT_FAILURE; return EXIT_FAILURE;
@ -165,7 +160,7 @@ main (int argc, char *argv[])
printf ("%s", "Done, emulated tag is initialized"); printf ("%s", "Done, emulated tag is initialized");
// Try to open the NFC reader // Try to open the NFC reader
pndReader = nfc_connect (&(pnddDevices[1])); pndReader = nfc_connect (connstrings[1]);
printf ("Connected to the NFC reader device: %s", pndReader->acName); printf ("Connected to the NFC reader device: %s", pndReader->acName);
printf ("%s", "Configuring NFC reader settings..."); printf ("%s", "Configuring NFC reader settings...");

View file

@ -55,7 +55,6 @@ main (int argc, const char *argv[])
size_t szFound; size_t szFound;
size_t i; size_t i;
nfc_device_t *pnd; nfc_device_t *pnd;
nfc_device_desc_t *pnddDevices;
const char *acLibnfcVersion; const char *acLibnfcVersion;
bool result; bool result;
@ -72,19 +71,15 @@ main (int argc, const char *argv[])
acLibnfcVersion = nfc_version (); acLibnfcVersion = nfc_version ();
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion); printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) { nfc_connstring connstrings[MAX_DEVICE_COUNT];
fprintf (stderr, "malloc() failed\n"); nfc_list_devices (connstrings, MAX_DEVICE_COUNT, &szFound);
return EXIT_FAILURE;
}
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound);
if (szFound == 0) { if (szFound == 0) {
printf ("No NFC device found.\n"); printf ("No NFC device found.\n");
} }
for (i = 0; i < szFound; i++) { for (i = 0; i < szFound; i++) {
pnd = nfc_connect (&(pnddDevices[i])); pnd = nfc_connect (connstrings[i]);
if (pnd == NULL) { if (pnd == NULL) {
ERR ("%s", "Unable to connect to NFC device."); ERR ("%s", "Unable to connect to NFC device.");

View file

@ -71,24 +71,7 @@ typedef struct {
int iLastError; int iLastError;
} nfc_device_t; } nfc_device_t;
/** typedef char nfc_connstring[1024];
* @struct nfc_device_desc_t
* @brief NFC device description
*
* This struct is used to try to connect to a specified nfc device when nfc_connect(...)
*/
typedef struct {
/** Device name (e.g. "ACS ACR 38U-CCID 00 00") */
char acDevice[DEVICE_NAME_LENGTH];
/** Driver name (e.g. "PN532_UART")*/
char *pcDriver;
/** Port (e.g. "/dev/ttyUSB0") */
char acPort[DEVICE_PORT_LENGTH];
/** Port speed (e.g. "115200") */
uint32_t uiSpeed;
/** Device index for backward compatibility (used to choose one specific device in USB or PSCS devices list) */
uint32_t uiBusIndex;
} nfc_device_desc_t;
// Compiler directive, set struct alignment to 1 byte_t for compatibility // Compiler directive, set struct alignment to 1 byte_t for compatibility
# pragma pack(1) # pragma pack(1)

View file

@ -63,10 +63,11 @@ extern "C" {
# endif // __cplusplus # endif // __cplusplus
/* NFC Device/Hardware manipulation */ /* NFC Device/Hardware manipulation */
NFC_EXPORT nfc_device_t *nfc_connect (nfc_device_desc_t * pndd); NFC_EXPORT bool nfc_get_default_device (nfc_connstring *connstring);
NFC_EXPORT nfc_device_t *nfc_connect (const nfc_connstring connstring);
NFC_EXPORT void nfc_disconnect (nfc_device_t * pnd); NFC_EXPORT void nfc_disconnect (nfc_device_t * pnd);
NFC_EXPORT bool nfc_abort_command (nfc_device_t * pnd); NFC_EXPORT bool 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_connstring connstrings[], size_t connstrings_len, 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);
NFC_EXPORT bool nfc_idle (nfc_device_t * pnd); NFC_EXPORT bool nfc_idle (nfc_device_t * pnd);

View file

@ -40,7 +40,7 @@
// Bus // Bus
#include <winscard.h> #include <winscard.h>
# define ACR122_DRIVER_NAME "ACR122" #define ACR122_DRIVER_NAME "acr122"
#if defined (_WIN32) #if defined (_WIN32)
# define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE SCARD_CTL_CODE(3500) # define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE SCARD_CTL_CODE(3500)
@ -133,7 +133,7 @@ acr122_free_scardcontext (void)
* @return true if succeeded, false otherwise. * @return true if succeeded, false otherwise.
*/ */
bool bool
acr122_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound) acr122_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t * pszDeviceFound)
{ {
size_t szPos = 0; size_t szPos = 0;
char acDeviceNames[256 + 64 * PCSC_MAX_DEVICES]; char acDeviceNames[256 + 64 * PCSC_MAX_DEVICES];
@ -158,9 +158,7 @@ acr122_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
if (SCardListReaders (*pscc, NULL, acDeviceNames, &dwDeviceNamesLen) != SCARD_S_SUCCESS) if (SCardListReaders (*pscc, NULL, acDeviceNames, &dwDeviceNamesLen) != SCARD_S_SUCCESS)
return false; return false;
// DBG("%s", "PCSC reports following device(s):"); while ((acDeviceNames[szPos] != '\0') && ((*pszDeviceFound) < connstrings_len)) {
while ((acDeviceNames[szPos] != '\0') && ((*pszDeviceFound) < szDevices)) {
uiBusIndex++; uiBusIndex++;
// DBG("- %s (pos=%ld)", acDeviceNames + szPos, (unsigned long) szPos); // DBG("- %s (pos=%ld)", acDeviceNames + szPos, (unsigned long) szPos);
@ -173,9 +171,7 @@ acr122_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
if (bSupported) { if (bSupported) {
// Supported ACR122 device found // Supported ACR122 device found
strncpy (pnddDevices[*pszDeviceFound].acDevice, acDeviceNames + szPos, DEVICE_NAME_LENGTH - 1); snprintf (connstrings[*pszDeviceFound], sizeof(nfc_connstring), "%s:%s:%"PRIu32, ACR122_DRIVER_NAME, acDeviceNames + szPos, uiBusIndex);
pnddDevices[*pszDeviceFound].pcDriver = ACR122_DRIVER_NAME;
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
(*pszDeviceFound)++; (*pszDeviceFound)++;
} else { } else {
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "PCSC device [%s] is not NFC capable or not supported by libnfc.", acDeviceNames + szPos); log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "PCSC device [%s] is not NFC capable or not supported by libnfc.", acDeviceNames + szPos);
@ -189,9 +185,71 @@ acr122_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
return true; return true;
} }
nfc_device_t * struct acr122_descriptor {
acr122_connect (const nfc_device_desc_t * pndd) char pcsc_device_name[512];
int bus_index;
};
int
acr122_connstring_decode (const nfc_connstring connstring, struct acr122_descriptor *desc)
{ {
char *cs = malloc (strlen (connstring) + 1);
if (!cs) {
perror ("malloc");
return -1;
}
strcpy (cs, connstring);
const char *driver_name = strtok (cs, ":");
if (!driver_name) {
// Parse error
free (cs);
return -1;
}
if (0 != strcmp (driver_name, ACR122_DRIVER_NAME)) {
// Driver name does not match.
free (cs);
return 0;
}
const char *device_name = strtok (NULL, ":");
if (!device_name) {
// Only driver name was specified (or parsing error)
free (cs);
return 1;
}
strncpy (desc->pcsc_device_name, device_name, sizeof(desc->pcsc_device_name)-1);
desc->pcsc_device_name[sizeof(desc->pcsc_device_name)-1] = '\0';
const char *bus_index_s = strtok (NULL, ":");
if (!bus_index_s) {
// bus index not specified (or parsing error)
free (cs);
return 2;
}
unsigned long bus_index;
if (sscanf (bus_index_s, "%lu", &bus_index) != 1) {
// bus_index_s is not a number
free (cs);
return 2;
}
desc->bus_index = bus_index;
free (cs);
return 3;
}
nfc_device_t *
acr122_connect (const nfc_connstring connstring)
{
struct acr122_descriptor ndd;
int connstring_decode_level = acr122_connstring_decode (connstring, &ndd);
if (connstring_decode_level < 2) {
return NULL;
}
// FIXME: acr122_connect() does not take care about bus index
char *pcFirmware; char *pcFirmware;
nfc_device_t *pnd = nfc_device_new (); nfc_device_t *pnd = nfc_device_new ();
pnd->driver_data = malloc (sizeof (struct acr122_data)); pnd->driver_data = malloc (sizeof (struct acr122_data));
@ -201,14 +259,14 @@ acr122_connect (const nfc_device_desc_t * pndd)
SCARDCONTEXT *pscc; SCARDCONTEXT *pscc;
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to connect to %s", pndd->acDevice); log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to connect to %s", ndd.pcsc_device_name);
// Test if context succeeded // Test if context succeeded
if (!(pscc = acr122_get_scardcontext ())) if (!(pscc = acr122_get_scardcontext ()))
goto error; goto error;
// Test if we were able to connect to the "emulator" card // Test if we were able to connect to the "emulator" card
if (SCardConnect (*pscc, pndd->acDevice, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &(DRIVER_DATA (pnd)->hCard), (void *) &(DRIVER_DATA (pnd)->ioCard.dwProtocol)) != SCARD_S_SUCCESS) { if (SCardConnect (*pscc, ndd.pcsc_device_name, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &(DRIVER_DATA (pnd)->hCard), (void *) &(DRIVER_DATA (pnd)->ioCard.dwProtocol)) != SCARD_S_SUCCESS) {
// Connect to ACR122 firmware version >2.0 // Connect to ACR122 firmware version >2.0
if (SCardConnect (*pscc, pndd->acDevice, SCARD_SHARE_DIRECT, 0, &(DRIVER_DATA (pnd)->hCard), (void *) &(DRIVER_DATA (pnd)->ioCard.dwProtocol)) != SCARD_S_SUCCESS) { if (SCardConnect (*pscc, ndd.pcsc_device_name, SCARD_SHARE_DIRECT, 0, &(DRIVER_DATA (pnd)->hCard), (void *) &(DRIVER_DATA (pnd)->ioCard.dwProtocol)) != SCARD_S_SUCCESS) {
// We can not connect to this device. // We can not connect to this device.
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%s", "PCSC connect failed"); log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%s", "PCSC connect failed");
goto error; goto error;
@ -222,7 +280,7 @@ acr122_connect (const nfc_device_desc_t * pndd)
if (strstr (pcFirmware, FIRMWARE_TEXT) != NULL) { if (strstr (pcFirmware, FIRMWARE_TEXT) != NULL) {
// Done, we found the reader we are looking for // Done, we found the reader we are looking for
snprintf (pnd->acName, sizeof (pnd->acName), "%s / %s", pndd->acDevice, pcFirmware); snprintf (pnd->acName, sizeof (pnd->acName), "%s / %s", ndd.pcsc_device_name, pcFirmware);
// 50: empirical tuning on Touchatag // 50: empirical tuning on Touchatag
// 46: empirical tuning on ACR122U // 46: empirical tuning on ACR122U
@ -407,11 +465,11 @@ const struct pn53x_io acr122_io = {
}; };
const struct nfc_driver_t acr122_driver = { const struct nfc_driver_t acr122_driver = {
.name = ACR122_DRIVER_NAME, .name = ACR122_DRIVER_NAME,
.probe = acr122_probe, .probe = acr122_probe,
.connect = acr122_connect, .connect = acr122_connect,
.disconnect = acr122_disconnect, .disconnect = acr122_disconnect,
.strerror = pn53x_strerror, .strerror = pn53x_strerror,
.initiator_init = pn53x_initiator_init, .initiator_init = pn53x_initiator_init,
.initiator_select_passive_target = pn53x_initiator_select_passive_target, .initiator_select_passive_target = pn53x_initiator_select_passive_target,
@ -431,7 +489,7 @@ const struct nfc_driver_t acr122_driver = {
.configure = pn53x_configure, .configure = pn53x_configure,
.abort_command = NULL, .abort_command = NULL, // FIXME: abort is not supported in this driver
.idle = NULL, .idle = NULL, // FIXME: idle is not supported in this driver
}; };

View file

@ -26,10 +26,10 @@
# include <nfc/nfc-types.h> # include <nfc/nfc-types.h>
bool acr122_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound); bool acr122_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t * pszDeviceFound);
// Functions used by developer to handle connection to this device // Functions used by developer to handle connection to this device
nfc_device_t *acr122_connect (const nfc_device_desc_t * pndd); nfc_device_t *acr122_connect (const nfc_connstring connstring);
bool acr122_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout); bool acr122_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout);
int acr122_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struct timeval *timeout); int acr122_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struct timeval *timeout);
void acr122_disconnect (nfc_device_t * pnd); void acr122_disconnect (nfc_device_t * pnd);

View file

@ -26,6 +26,9 @@
* This driver can handle ARYGON readers that use UART as bus. * This driver can handle ARYGON readers that use UART as bus.
* UART connection can be direct (host<->arygon_uc) or could be provided by internal USB to serial interface (e.g. host<->ftdi_chip<->arygon_uc) * UART connection can be direct (host<->arygon_uc) or could be provided by internal USB to serial interface (e.g. host<->ftdi_chip<->arygon_uc)
*/ */
/* vim: set ts=2 sw=2 et: */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include "config.h" # include "config.h"
#endif // HAVE_CONFIG_H #endif // HAVE_CONFIG_H
@ -33,6 +36,7 @@
#include "arygon.h" #include "arygon.h"
#include <stdio.h> #include <stdio.h>
#include <inttypes.h>
#include <string.h> #include <string.h>
#include <sys/param.h> #include <sys/param.h>
#include <string.h> #include <string.h>
@ -64,7 +68,7 @@
#define DEV_ARYGON_PROTOCOL_TAMA_WAB '3' #define DEV_ARYGON_PROTOCOL_TAMA_WAB '3'
#define ARYGON_DEFAULT_SPEED 9600 #define ARYGON_DEFAULT_SPEED 9600
#define ARYGON_DRIVER_NAME "ARYGON" #define ARYGON_DRIVER_NAME "arygon"
#define LOG_CATEGORY "libnfc.driver.arygon" #define LOG_CATEGORY "libnfc.driver.arygon"
#define DRIVER_DATA(pnd) ((struct arygon_data*)(pnd->driver_data)) #define DRIVER_DATA(pnd) ((struct arygon_data*)(pnd->driver_data))
@ -88,16 +92,16 @@ 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 bool
arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound) arygon_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t * pszDeviceFound)
{ {
/** @note: Due to UART bus we can't know if its really an ARYGON without /** @note: Due to UART bus we can't know if its really an ARYGON without
* sending some commands. But using this way to probe devices, we can * sending some commands. But using this way to probe devices, we can
* have serious problem with other device on this bus */ * have serious problem with other device on this bus */
#ifndef SERIAL_AUTOPROBE_ENABLED #ifndef SERIAL_AUTOPROBE_ENABLED
(void) pnddDevices; (void) connstrings;
(void) szDevices; (void) connstrings_len;
*pszDeviceFound = 0; *pszDeviceFound = 0;
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%s", "Serial auto-probing have been disabled at compile time. Skipping autoprobe."); log_put (LOG_CATEGORY, NFC_PRIORITY_INFO, "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
return false; return false;
#else /* SERIAL_AUTOPROBE_ENABLED */ #else /* SERIAL_AUTOPROBE_ENABLED */
*pszDeviceFound = 0; *pszDeviceFound = 0;
@ -135,24 +139,18 @@ arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
pn53x_data_free (pnd); pn53x_data_free (pnd);
nfc_device_free (pnd); nfc_device_free (pnd);
uart_close (sp); uart_close (sp);
if(!res) if(!res) {
continue; continue;
}
// ARYGON reader is found // ARYGON reader is found
snprintf (pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "Arygon", acPort); snprintf (connstrings[*pszDeviceFound], sizeof(nfc_connstring), "%s:%s:%"PRIu32, ARYGON_DRIVER_NAME, acPort, ARYGON_DEFAULT_SPEED);
pnddDevices[*pszDeviceFound].pcDriver = ARYGON_DRIVER_NAME;
strncpy (pnddDevices[*pszDeviceFound].acPort, acPort, DEVICE_PORT_LENGTH - 1); pnddDevices[*pszDeviceFound].acPort[DEVICE_PORT_LENGTH - 1] = '\0';
pnddDevices[*pszDeviceFound].uiSpeed = ARYGON_DEFAULT_SPEED;
(*pszDeviceFound)++; (*pszDeviceFound)++;
// Test if we reach the maximum "wanted" devices // Test if we reach the maximum "wanted" devices
if ((*pszDeviceFound) >= szDevices) if ((*pszDeviceFound) >= connstrings_len)
break; break;
} }
if (sp == INVALID_SERIAL_PORT)
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Invalid serial port: %s", acPort);
if (sp == CLAIMED_SERIAL_PORT)
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Serial port already claimed: %s", acPort);
} }
iDevice = 0; iDevice = 0;
while ((acPort = acPorts[iDevice++])) { while ((acPort = acPorts[iDevice++])) {
@ -163,29 +161,92 @@ arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
return true; return true;
} }
nfc_device_t * struct arygon_descriptor {
arygon_connect (const nfc_device_desc_t * pndd) char port[128];
uint32_t speed;
};
int
arygon_connstring_decode (const nfc_connstring connstring, struct arygon_descriptor *desc)
{ {
char *cs = malloc (strlen (connstring) + 1);
if (!cs) {
perror ("malloc");
return -1;
}
strcpy (cs, connstring);
const char *driver_name = strtok (cs, ":");
if (!driver_name) {
// Parse error
free (cs);
return -1;
}
if (0 != strcmp (driver_name, ARYGON_DRIVER_NAME)) {
// Driver name does not match.
free (cs);
return 0;
}
const char *port = strtok (NULL, ":");
if (!port) {
// Only driver name was specified (or parsing error)
free (cs);
return 1;
}
strncpy (desc->port, port, sizeof(desc->port)-1);
desc->port[sizeof(desc->port)-1] = '\0';
const char* speed_s = strtok (NULL, ":");
if (!speed_s) {
// speed not specified (or parsing error)
free (cs);
return 2;
}
unsigned long speed;
if (sscanf (speed_s, "%lu", &speed) != 1) {
// speed_s is not a number
free (cs);
return 2;
}
desc->speed = speed;
free (cs);
return 3;
}
nfc_device_t *
arygon_connect (const nfc_connstring connstring)
{
struct arygon_descriptor ndd;
int connstring_decode_level = arygon_connstring_decode (connstring, &ndd);
if (connstring_decode_level < 2) {
return NULL;
}
if (connstring_decode_level < 3) {
ndd.speed = ARYGON_DEFAULT_SPEED;
}
serial_port sp; serial_port sp;
nfc_device_t *pnd = NULL; nfc_device_t *pnd = NULL;
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to connect to: %s at %d bauds.", pndd->acPort, pndd->uiSpeed); log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to connect to: %s at %d bauds.", ndd.port, ndd.speed);
sp = uart_open (pndd->acPort); sp = uart_open (ndd.port);
if (sp == INVALID_SERIAL_PORT) if (sp == INVALID_SERIAL_PORT)
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Invalid serial port: %s", pndd->acPort); log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Invalid serial port: %s", ndd.port);
if (sp == CLAIMED_SERIAL_PORT) if (sp == CLAIMED_SERIAL_PORT)
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Serial port already claimed: %s", pndd->acPort); log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Serial port already claimed: %s", ndd.port);
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
return NULL; return NULL;
// We need to flush input to be sure first reply does not comes from older byte transceive // We need to flush input to be sure first reply does not comes from older byte transceive
uart_flush_input (sp); uart_flush_input (sp);
uart_set_speed (sp, pndd->uiSpeed); uart_set_speed (sp, ndd.speed);
// We have a connection // We have a connection
pnd = nfc_device_new (); pnd = nfc_device_new ();
strncpy (pnd->acName, pndd->acDevice, sizeof (pnd->acName)); snprintf (pnd->acName, sizeof (pnd->acName), "%s:%s", ARYGON_DRIVER_NAME, ndd.port);
pnd->driver_data = malloc(sizeof(struct arygon_data)); pnd->driver_data = malloc(sizeof(struct arygon_data));
DRIVER_DATA (pnd)->port = sp; DRIVER_DATA (pnd)->port = sp;
@ -209,7 +270,7 @@ arygon_connect (const nfc_device_desc_t * pndd)
// Check communication using "Reset TAMA" command // Check communication using "Reset TAMA" command
if (!arygon_reset_tama(pnd)) { if (!arygon_reset_tama(pnd)) {
nfc_device_free (pnd); arygon_disconnect (pnd);
return NULL; return NULL;
} }
@ -314,7 +375,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
#ifndef WIN32 #ifndef WIN32
abort_p = &(DRIVER_DATA (pnd)->iAbortFds[1]); abort_p = &(DRIVER_DATA (pnd)->iAbortFds[1]);
#else #else
abort_p = &(DRIVER_DATA (pnd)->abort_flag); abort_p = (void*)&(DRIVER_DATA (pnd)->abort_flag);
#endif #endif
pnd->iLastError = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 5, abort_p, timeout); pnd->iLastError = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 5, abort_p, timeout);
@ -500,11 +561,11 @@ const struct pn53x_io arygon_tama_io = {
}; };
const struct nfc_driver_t arygon_driver = { const struct nfc_driver_t arygon_driver = {
.name = ARYGON_DRIVER_NAME, .name = ARYGON_DRIVER_NAME,
.probe = arygon_probe, .probe = arygon_probe,
.connect = arygon_connect, .connect = arygon_connect,
.disconnect = arygon_disconnect, .disconnect = arygon_disconnect,
.strerror = pn53x_strerror, .strerror = pn53x_strerror,
.initiator_init = pn53x_initiator_init, .initiator_init = pn53x_initiator_init,
.initiator_select_passive_target = pn53x_initiator_select_passive_target, .initiator_select_passive_target = pn53x_initiator_select_passive_target,
@ -525,7 +586,6 @@ const struct nfc_driver_t arygon_driver = {
.configure = pn53x_configure, .configure = pn53x_configure,
.abort_command = arygon_abort_command, .abort_command = arygon_abort_command,
// FIXME Implement me .idle = NULL, // FIXME arygon driver does not support idle()
.idle = NULL,
}; };

View file

@ -30,9 +30,9 @@
# include <nfc/nfc-types.h> # include <nfc/nfc-types.h>
bool arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound); bool arygon_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t * pszDeviceFound);
nfc_device_t *arygon_connect (const nfc_device_desc_t * pndd); nfc_device_t *arygon_connect (const nfc_connstring connstring);
void arygon_disconnect (nfc_device_t * pnd); void arygon_disconnect (nfc_device_t * pnd);
bool arygon_tama_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout); bool arygon_tama_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout);

View file

@ -32,6 +32,7 @@
#include "pn532_uart.h" #include "pn532_uart.h"
#include <stdio.h> #include <stdio.h>
#include <inttypes.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -44,7 +45,7 @@
#include "uart.h" #include "uart.h"
#define PN532_UART_DEFAULT_SPEED 115200 #define PN532_UART_DEFAULT_SPEED 115200
#define PN532_UART_DRIVER_NAME "PN532_UART" #define PN532_UART_DRIVER_NAME "pn532_uart"
#define LOG_CATEGORY "libnfc.driver.pn532_uart" #define LOG_CATEGORY "libnfc.driver.pn532_uart"
int pn532_uart_ack (nfc_device_t * pnd); int pn532_uart_ack (nfc_device_t * pnd);
@ -64,14 +65,14 @@ struct pn532_uart_data {
#define DRIVER_DATA(pnd) ((struct pn532_uart_data*)(pnd->driver_data)) #define DRIVER_DATA(pnd) ((struct pn532_uart_data*)(pnd->driver_data))
bool bool
pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound) pn532_uart_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t * pszDeviceFound)
{ {
/** @note: Due to UART bus we can't know if its really a pn532 without /** @note: Due to UART bus we can't know if its really a pn532 without
* sending some PN53x commands. But using this way to probe devices, we can * sending some PN53x commands. But using this way to probe devices, we can
* have serious problem with other device on this bus */ * have serious problem with other device on this bus */
#ifndef SERIAL_AUTOPROBE_ENABLED #ifndef SERIAL_AUTOPROBE_ENABLED
(void) pnddDevices; (void) connstrings;
(void) szDevices; (void) connstrings_len;
*pszDeviceFound = 0; *pszDeviceFound = 0;
log_put (LOG_CATEGORY, NFC_PRIORITY_INFO, "Serial auto-probing have been disabled at compile time. Skipping autoprobe."); log_put (LOG_CATEGORY, NFC_PRIORITY_INFO, "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
return false; return false;
@ -124,18 +125,14 @@ pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps
continue; continue;
} }
snprintf (pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "PN532", acPort); snprintf (connstrings[*pszDeviceFound], sizeof(nfc_connstring), "%s:%s:%"PRIu32, PN532_UART_DRIVER_NAME, acPort, PN532_UART_DEFAULT_SPEED);
pnddDevices[*pszDeviceFound].pcDriver = PN532_UART_DRIVER_NAME;
strncpy (pnddDevices[*pszDeviceFound].acPort, acPort, DEVICE_PORT_LENGTH - 1); pnddDevices[*pszDeviceFound].acPort[DEVICE_PORT_LENGTH - 1] = '\0';
pnddDevices[*pszDeviceFound].uiSpeed = PN532_UART_DEFAULT_SPEED;
(*pszDeviceFound)++; (*pszDeviceFound)++;
// Test if we reach the maximum "wanted" devices // Test if we reach the maximum "wanted" devices
if ((*pszDeviceFound) >= szDevices) if ((*pszDeviceFound) >= connstrings_len)
break; break;
} }
} }
iDevice = 0; iDevice = 0;
while ((acPort = acPorts[iDevice++])) { while ((acPort = acPorts[iDevice++])) {
free ((void*)acPort); free ((void*)acPort);
@ -145,33 +142,96 @@ pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps
return true; return true;
} }
nfc_device_t * struct pn532_uart_descriptor {
pn532_uart_connect (const nfc_device_desc_t * pndd) char port[128];
uint32_t speed;
};
int
pn532_connstring_decode (const nfc_connstring connstring, struct pn532_uart_descriptor *desc)
{ {
char *cs = malloc (strlen (connstring) + 1);
if (!cs) {
perror ("malloc");
return -1;
}
strcpy (cs, connstring);
const char *driver_name = strtok (cs, ":");
if (!driver_name) {
// Parse error
free (cs);
return -1;
}
if (0 != strcmp (driver_name, PN532_UART_DRIVER_NAME)) {
// Driver name does not match.
free (cs);
return 0;
}
const char *port = strtok (NULL, ":");
if (!port) {
// Only driver name was specified (or parsing error)
free (cs);
return 1;
}
strncpy (desc->port, port, sizeof(desc->port)-1);
desc->port[sizeof(desc->port)-1] = '\0';
const char* speed_s = strtok (NULL, ":");
if (!speed_s) {
// speed not specified (or parsing error)
free (cs);
return 2;
}
unsigned long speed;
if (sscanf (speed_s, "%lu", &speed) != 1) {
// speed_s is not a number
free (cs);
return 2;
}
desc->speed = speed;
free (cs);
return 3;
}
nfc_device_t *
pn532_uart_connect (const nfc_connstring connstring)
{
struct pn532_uart_descriptor ndd;
int connstring_decode_level = pn532_connstring_decode (connstring, &ndd);
if (connstring_decode_level < 2) {
return NULL;
}
if (connstring_decode_level < 3) {
ndd.speed = PN532_UART_DEFAULT_SPEED;
}
serial_port sp; serial_port sp;
nfc_device_t *pnd = NULL; nfc_device_t *pnd = NULL;
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to connect to: %s at %d bauds.", pndd->acPort, pndd->uiSpeed); log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Attempt to connect to: %s at %d bauds.", ndd.port, ndd.speed);
sp = uart_open (pndd->acPort); sp = uart_open (ndd.port);
if (sp == INVALID_SERIAL_PORT) if (sp == INVALID_SERIAL_PORT)
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Invalid serial port: %s", pndd->acPort); log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Invalid serial port: %s", ndd.port);
if (sp == CLAIMED_SERIAL_PORT) if (sp == CLAIMED_SERIAL_PORT)
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Serial port already claimed: %s", pndd->acPort); log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Serial port already claimed: %s", ndd.port);
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
return NULL; return NULL;
// We need to flush input to be sure first reply does not comes from older byte transceive // We need to flush input to be sure first reply does not comes from older byte transceive
uart_flush_input (sp); uart_flush_input (sp);
uart_set_speed (sp, pndd->uiSpeed); uart_set_speed (sp, ndd.speed);
// We have a connection // We have a connection
pnd = nfc_device_new (); pnd = nfc_device_new ();
strncpy (pnd->acName, pndd->acDevice, DEVICE_NAME_LENGTH - 1); snprintf (pnd->acName, sizeof (pnd->acName), "%s:%s", PN532_UART_DRIVER_NAME, ndd.port);
pnd->acName[DEVICE_NAME_LENGTH - 1] = '\0';
pnd->driver_data = malloc(sizeof(struct pn532_uart_data)); pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
DRIVER_DATA(pnd)->port = sp; DRIVER_DATA (pnd)->port = sp;
// Alloc and init chip's data // Alloc and init chip's data
pn53x_data_new (pnd, &pn532_uart_io); pn53x_data_new (pnd, &pn532_uart_io);
// SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532 // SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532
@ -193,7 +253,7 @@ pn532_uart_connect (const nfc_device_desc_t * pndd)
// Check communication using "Diagnose" command, with "Communication test" (0x00) // Check communication using "Diagnose" command, with "Communication test" (0x00)
if (!pn53x_check_communication (pnd)) { if (!pn53x_check_communication (pnd)) {
nfc_perror (pnd, "pn53x_check_communication"); nfc_perror (pnd, "pn53x_check_communication");
pn532_uart_disconnect(pnd); pn532_uart_disconnect (pnd);
return NULL; return NULL;
} }
@ -304,7 +364,7 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
abort_p = (void*)&(DRIVER_DATA (pnd)->abort_flag); abort_p = (void*)&(DRIVER_DATA (pnd)->abort_flag);
#endif #endif
pnd->iLastError = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 5, abort_p, timeout); pnd->iLastError = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 5, abort_p, timeout);
if (abort_p && (EOPABORT == pnd->iLastError)) { if (abort_p && (EOPABORT == pnd->iLastError)) {
pn532_uart_ack (pnd); pn532_uart_ack (pnd);
@ -325,7 +385,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 (DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout); uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 3, 0, timeout);
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Application level error detected"); log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Application level error detected");
pnd->iLastError = EFRAISERRFRAME; pnd->iLastError = EFRAISERRFRAME;
return -1; return -1;
@ -362,7 +422,7 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
} }
// TFI + PD0 (CC+1) // TFI + PD0 (CC+1)
pnd->iLastError = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout); pnd->iLastError = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
if (pnd->iLastError != 0) { if (pnd->iLastError != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)"); log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
return -1; return -1;
@ -381,14 +441,14 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
} }
if (len) { if (len) {
pnd->iLastError = uart_receive (DRIVER_DATA(pnd)->port, pbtData, len, 0, timeout); pnd->iLastError = uart_receive (DRIVER_DATA (pnd)->port, pbtData, len, 0, timeout);
if (pnd->iLastError != 0) { if (pnd->iLastError != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)"); log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
return -1; return -1;
} }
} }
pnd->iLastError = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout); pnd->iLastError = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
if (pnd->iLastError != 0) { if (pnd->iLastError != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)"); log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
return -1; return -1;
@ -446,11 +506,11 @@ const struct pn53x_io pn532_uart_io = {
}; };
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,
.connect = pn532_uart_connect, .connect = pn532_uart_connect,
.disconnect = pn532_uart_disconnect, .disconnect = pn532_uart_disconnect,
.strerror = pn53x_strerror, .strerror = pn53x_strerror,
.initiator_init = pn53x_initiator_init, .initiator_init = pn53x_initiator_init,
.initiator_select_passive_target = pn53x_initiator_select_passive_target, .initiator_select_passive_target = pn53x_initiator_select_passive_target,

View file

@ -29,9 +29,9 @@
# include <nfc/nfc-types.h> # include <nfc/nfc-types.h>
bool pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound); bool pn532_uart_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t * pszDeviceFound);
nfc_device_t *pn532_uart_connect (const nfc_device_desc_t * pndd); nfc_device_t *pn532_uart_connect (const nfc_connstring connstring);
void pn532_uart_disconnect (nfc_device_t * pnd); void pn532_uart_disconnect (nfc_device_t * pnd);
bool pn532_uart_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout); bool pn532_uart_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout);
int pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struct timeval *timeout); int pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struct timeval *timeout);

View file

@ -32,10 +32,11 @@
Thanks to d18c7db and Okko for example code Thanks to d18c7db and Okko for example code
*/ */
#include <sys/select.h>
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <inttypes.h>
#include <sys/select.h>
#include <errno.h>
#ifndef _WIN32 #ifndef _WIN32
// Under POSIX system, we use libusb (>= 0.1.12) // Under POSIX system, we use libusb (>= 0.1.12)
@ -58,7 +59,7 @@ Thanks to d18c7db and Okko for example code
#include "chips/pn53x-internal.h" #include "chips/pn53x-internal.h"
#include "drivers/pn53x_usb.h" #include "drivers/pn53x_usb.h"
#define PN53X_USB_DRIVER_NAME "PN53x USB" #define PN53X_USB_DRIVER_NAME "pn53x_usb"
#define LOG_CATEGORY "libnfc.driver.pn53x_usb" #define LOG_CATEGORY "libnfc.driver.pn53x_usb"
#define USB_INFINITE_TIMEOUT 0 #define USB_INFINITE_TIMEOUT 0
@ -222,7 +223,7 @@ pn53x_usb_get_end_points (struct usb_device *dev, struct pn53x_usb_data *data)
} }
bool bool
pn53x_usb_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound) pn53x_usb_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t * pszDeviceFound)
{ {
usb_init (); usb_init ();
@ -275,13 +276,13 @@ pn53x_usb_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * psz
continue; continue;
} }
pn53x_usb_get_usb_device_name (dev, udev, pnddDevices[*pszDeviceFound].acDevice, sizeof (pnddDevices[*pszDeviceFound].acDevice)); // pn53x_usb_get_usb_device_name (dev, udev, pnddDevices[*pszDeviceFound].acDevice, sizeof (pnddDevices[*pszDeviceFound].acDevice));
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "device found: Bus %s Device %s", bus->dirname, dev->filename);
usb_close (udev); usb_close (udev);
pnddDevices[*pszDeviceFound].pcDriver = PN53X_USB_DRIVER_NAME; snprintf (connstrings[*pszDeviceFound], sizeof(nfc_connstring), "%s:%s:%s", PN53X_USB_DRIVER_NAME, bus->dirname, dev->filename);
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
(*pszDeviceFound)++; (*pszDeviceFound)++;
// Test if we reach the maximum "wanted" devices // Test if we reach the maximum "wanted" devices
if ((*pszDeviceFound) == szDevices) { if ((*pszDeviceFound) == connstrings_len) {
return true; return true;
} }
} }
@ -292,6 +293,64 @@ pn53x_usb_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * psz
return true; return true;
} }
struct pn53x_usb_descriptor {
uint16_t bus;
uint16_t dev;
};
int
pn53x_usb_connstring_decode (const nfc_connstring connstring, struct pn53x_usb_descriptor *desc)
{
char *cs = malloc (strlen (connstring) + 1);
if (!cs) {
perror ("malloc");
return -1;
}
strcpy (cs, connstring);
const char *driver_name = strtok (cs, ":");
if (!driver_name) {
// Parse error
free (cs);
return -1;
}
if (0 != strcmp (driver_name, PN53X_USB_DRIVER_NAME)) {
// Driver name does not match.
free (cs);
return 0;
}
const char *bus_s = strtok (NULL, ":");
if (!bus_s) {
// bus not specified (or parsing error)
free (cs);
return 1;
}
unsigned int bus;
if (sscanf (bus_s, "%u", &bus) != 1) {
// bus_s is not a number
free (cs);
return 1;
}
desc->bus = bus;
const char *dev_s = strtok (NULL, ":");
if (!dev_s) {
// dev not specified (or parsing error)
free (cs);
return 2;
}
unsigned int dev;
if (sscanf (dev_s, "%u", &dev) != 1) {
// dev_s is not a number
free (cs);
return 2;
}
desc->dev = dev;
free (cs);
return 3;
}
bool bool
pn53x_usb_get_usb_device_name (struct usb_device *dev, usb_dev_handle *udev, char *buffer, size_t len) pn53x_usb_get_usb_device_name (struct usb_device *dev, usb_dev_handle *udev, char *buffer, size_t len)
{ {
@ -320,8 +379,15 @@ pn53x_usb_get_usb_device_name (struct usb_device *dev, usb_dev_handle *udev, cha
} }
nfc_device_t * nfc_device_t *
pn53x_usb_connect (const nfc_device_desc_t *pndd) pn53x_usb_connect (const nfc_connstring connstring)
{ {
struct pn53x_usb_descriptor desc;
int connstring_decode_level = pn53x_usb_connstring_decode (connstring, &desc);
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%d element(s) have been decoded from \"%s\"", connstring_decode_level, connstring);
if (connstring_decode_level < 1) {
return NULL;
}
nfc_device_t *pnd = NULL; nfc_device_t *pnd = NULL;
struct pn53x_usb_data data = { struct pn53x_usb_data data = {
.pudh = NULL, .pudh = NULL,
@ -330,82 +396,90 @@ pn53x_usb_connect (const nfc_device_desc_t *pndd)
}; };
struct usb_bus *bus; struct usb_bus *bus;
struct usb_device *dev; struct usb_device *dev;
uint32_t uiBusIndex;
usb_init (); usb_init ();
uiBusIndex = pndd->uiBusIndex;
for (bus = usb_get_busses (); bus; bus = bus->next) { for (bus = usb_get_busses (); bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex--) { if (connstring_decode_level > 1) {
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Checking device %04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct); // A specific bus have been specified
if (uiBusIndex == 0) { unsigned int bus_current;
// Open the USB device sscanf (bus->dirname, "%u", &bus_current);
data.pudh = usb_open (dev); if (bus_current != desc.bus)
// Retrieve end points continue;
pn53x_usb_get_end_points (dev, &data); }
// Set configuration for (dev = bus->devices; dev; dev = dev->next) {
int res = usb_set_configuration (data.pudh, 1); if (connstring_decode_level > 2) {
if (res < 0) { // A specific dev have been specified
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to set USB configuration (%s)", _usb_strerror (res)); unsigned int dev_current;
if (EPERM == -res) { sscanf (dev->filename, "%u", &dev_current);
log_put (LOG_CATEGORY, NFC_PRIORITY_WARN, "Please double check USB permissions for device %04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct); if (dev_current != desc.dev)
} continue;
usb_close (data.pudh);
// we failed to use the specified device
return NULL;
}
res = usb_claim_interface (data.pudh, 0);
if (res < 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to claim USB interface (%s)", _usb_strerror (res));
usb_close (data.pudh);
// we failed to use the specified device
return NULL;
}
data.model = pn53x_usb_get_device_model (dev->descriptor.idVendor, dev->descriptor.idProduct);
// Allocate memory for the device info and specification, fill it and return the info
pnd = nfc_device_new ();
pn53x_usb_get_usb_device_name (dev, data.pudh, pnd->acName, sizeof (pnd->acName));
pnd->driver_data = malloc(sizeof(struct pn53x_usb_data));
*DRIVER_DATA (pnd) = data;
// Alloc and init chip's data
pn53x_data_new (pnd, &pn53x_usb_io);
switch (DRIVER_DATA (pnd)->model) {
// empirical tuning
case ASK_LOGO:
CHIP_DATA (pnd)->timer_correction = 50;
break;
case SCM_SCL3711:
case NXP_PN533:
CHIP_DATA (pnd)->timer_correction = 46;
break;
case NXP_PN531:
CHIP_DATA (pnd)->timer_correction = 50;
break;
case SONY_PN531:
CHIP_DATA (pnd)->timer_correction = 54;
break;
default:
break;
}
pnd->driver = &pn53x_usb_driver;
// HACK1: Send first an ACK as Abort command, to reset chip before talking to it:
pn53x_usb_ack (pnd);
// HACK2: Then send a GetFirmware command to resync USB toggle bit between host & device
// in case host used set_configuration and expects the device to have reset its toggle bit, which PN53x doesn't do
if (!pn53x_usb_init (pnd)) {
usb_close (data.pudh);
goto error;
}
DRIVER_DATA (pnd)->abort_flag = false;
return pnd;
} }
// Open the USB device
data.pudh = usb_open (dev);
// Retrieve end points
pn53x_usb_get_end_points (dev, &data);
// Set configuration
int res = usb_set_configuration (data.pudh, 1);
if (res < 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to set USB configuration (%s)", _usb_strerror (res));
if (EPERM == -res) {
log_put (LOG_CATEGORY, NFC_PRIORITY_WARN, "Please double check USB permissions for device %04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
}
usb_close (data.pudh);
// we failed to use the specified device
return NULL;
}
res = usb_claim_interface (data.pudh, 0);
if (res < 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to claim USB interface (%s)", _usb_strerror (res));
usb_close (data.pudh);
// we failed to use the specified device
return NULL;
}
data.model = pn53x_usb_get_device_model (dev->descriptor.idVendor, dev->descriptor.idProduct);
// Allocate memory for the device info and specification, fill it and return the info
pnd = nfc_device_new ();
pn53x_usb_get_usb_device_name (dev, data.pudh, pnd->acName, sizeof (pnd->acName));
pnd->driver_data = malloc(sizeof(struct pn53x_usb_data));
*DRIVER_DATA (pnd) = data;
// Alloc and init chip's data
pn53x_data_new (pnd, &pn53x_usb_io);
switch (DRIVER_DATA (pnd)->model) {
// empirical tuning
case ASK_LOGO:
CHIP_DATA (pnd)->timer_correction = 50;
break;
case SCM_SCL3711:
case NXP_PN533:
CHIP_DATA (pnd)->timer_correction = 46;
break;
case NXP_PN531:
CHIP_DATA (pnd)->timer_correction = 50;
break;
case SONY_PN531:
CHIP_DATA (pnd)->timer_correction = 54;
break;
default:
break;
}
pnd->driver = &pn53x_usb_driver;
// HACK1: Send first an ACK as Abort command, to reset chip before talking to it:
pn53x_usb_ack (pnd);
// HACK2: Then send a GetFirmware command to resync USB toggle bit between host & device
// in case host used set_configuration and expects the device to have reset its toggle bit, which PN53x doesn't do
if (!pn53x_usb_init (pnd)) {
usb_close (data.pudh);
goto error;
}
DRIVER_DATA (pnd)->abort_flag = false;
return pnd;
} }
} }
// We ran out of devices before the index required // We ran out of devices before the index required
@ -744,11 +818,11 @@ const struct pn53x_io pn53x_usb_io = {
}; };
const struct nfc_driver_t pn53x_usb_driver = { const struct nfc_driver_t pn53x_usb_driver = {
.name = PN53X_USB_DRIVER_NAME, .name = PN53X_USB_DRIVER_NAME,
.probe = pn53x_usb_probe, .probe = pn53x_usb_probe,
.connect = pn53x_usb_connect, .connect = pn53x_usb_connect,
.disconnect = pn53x_usb_disconnect, .disconnect = pn53x_usb_disconnect,
.strerror = pn53x_strerror, .strerror = pn53x_strerror,
.initiator_init = pn53x_initiator_init, .initiator_init = pn53x_initiator_init,
.initiator_select_passive_target = pn53x_initiator_select_passive_target, .initiator_select_passive_target = pn53x_initiator_select_passive_target,

View file

@ -29,8 +29,8 @@
# include <nfc/nfc-types.h> # include <nfc/nfc-types.h>
bool pn53x_usb_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound); bool pn53x_usb_probe (nfc_connstring connstrings[], size_t connstrings_len, size_t * pszDeviceFound);
nfc_device_t *pn53x_usb_connect (const nfc_device_desc_t * pndd); nfc_device_t *pn53x_usb_connect (const nfc_connstring connstring);
bool pn53x_usb_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout); bool pn53x_usb_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData, struct timeval *timeout);
int pn53x_usb_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struct timeval *timeout); int pn53x_usb_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szData, struct timeval *timeout);
void pn53x_usb_disconnect (nfc_device_t * pnd); void pn53x_usb_disconnect (nfc_device_t * pnd);

View file

@ -126,10 +126,10 @@
struct nfc_driver_t { struct nfc_driver_t {
const char *name; const char *name;
bool (*probe)(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound); bool (*probe)(nfc_connstring connstrings[], size_t connstrings_len, size_t * pszDeviceFound);
nfc_device_t * (*connect)(const nfc_device_desc_t * pndd); nfc_device_t * (*connect) (const nfc_connstring connstring);
void (*disconnect)(nfc_device_t * pnd); void (*disconnect) (nfc_device_t * pnd);
const char *(*strerror)(const nfc_device_t * pnd); const char *(*strerror) (const nfc_device_t * pnd);
bool (*initiator_init) (nfc_device_t * pnd); bool (*initiator_init) (nfc_device_t * pnd);
bool (*initiator_select_passive_target) (nfc_device_t * pnd, const nfc_modulation_t nm, const byte_t * pbtInitData, const size_t szInitData, nfc_target_t * pnt); bool (*initiator_select_passive_target) (nfc_device_t * pnd, const nfc_modulation_t nm, const byte_t * pbtInitData, const size_t szInitData, nfc_target_t * pnt);

View file

@ -61,63 +61,98 @@ const struct nfc_driver_t *nfc_drivers[] = {
NULL NULL
}; };
/**
* @brief Get the defaut NFC device
* @param connstring \a nfc_connstring pointer where the default connection string will be stored
* @return \e true on success
*
* This function fill \e connstring with the LIBNFC_DEFAULT_DEVICE environment variable content
* if is set otherwise it will search for the first available device, and fill
* \e connstring with the corresponding \a nfc_connstring value.
*
* This function returns true when LIBNFC_DEFAULT_DEVICE is set or an available device is found.
*
* @note The \e connstring content can be invalid if LIBNFC_DEFAULT_DEVICE is
* set with incorrect value.
*/
bool
nfc_get_default_device (nfc_connstring *connstring)
{
char * env_default_connstring = getenv ("LIBNFC_DEFAULT_DEVICE");
if (NULL == env_default_connstring) {
// LIBNFC_DEFAULT_DEVICE is not set, we fallback on probing for the first available device
size_t szDeviceFound;
nfc_connstring listed_cs[1];
nfc_list_devices (listed_cs, 1, &szDeviceFound);
if (szDeviceFound) {
strncpy (*connstring, listed_cs[0], sizeof(nfc_connstring));
} else {
return false;
}
} else {
strncpy (*connstring, env_default_connstring, sizeof(nfc_connstring));
}
return true;
}
/** /**
* @brief Connect to a NFC device * @brief Connect to a NFC device
* @param pndd device description if specific device is wanted, \c NULL otherwise * @param connstring The device connection string if specific device is wanted, \c NULL otherwise
* @return Returns pointer to a \a nfc_device_t struct if successfull; otherwise returns \c NULL value. * @return Returns pointer to a \a nfc_device_t struct if successfull; otherwise returns \c NULL value.
* *
* If \e pndd is \c NULL, the first available NFC device is claimed. * If \e connstring is \c NULL, the \a nfc_get_default_device() function is used.
* It will automatically search the system using all available drivers to determine a device is NFC-enabled.
* *
* If \e pndd is passed then this function will try to claim the right device using information provided by the \a nfc_device_desc_t struct. * If \e connstring is set, this function will try to claim the right device using information provided by \e connstring.
* *
* When it has successfully claimed a NFC device, memory is allocated to save the device information. It will return a pointer to a \a nfc_device_t struct. * When it has successfully claimed a NFC device, memory is allocated to save the device information.
* It will return a pointer to a \a nfc_device_t struct.
* This pointer should be supplied by every next functions of libnfc that should perform an action with this device. * This pointer should be supplied by every next functions of libnfc that should perform an action with this device.
* *
* @note Depending on the desired operation mode, the device needs to be configured * @note Depending on the desired operation mode, the device needs to be configured by using nfc_initiator_init() or nfc_target_init(),
* by using nfc_initiator_init() or nfc_target_init(), optionally followed by manual tuning of the parameters if the default parameters are not suiting your goals. * optionally followed by manual tuning of the parameters if the default parameters are not suiting your goals.
*/ */
nfc_device_t * nfc_device_t *
nfc_connect (nfc_device_desc_t * pndd) nfc_connect (const nfc_connstring connstring)
{ {
log_init ();
nfc_device_t *pnd = NULL; nfc_device_t *pnd = NULL;
if (pndd == NULL) { nfc_connstring ncs;
size_t szDeviceFound; if (connstring == NULL) {
nfc_device_desc_t ndd[1]; if (!nfc_get_default_device (&ncs)) {
nfc_list_devices (ndd, 1, &szDeviceFound); log_fini ();
if (szDeviceFound) { return NULL;
pndd = &ndd[0];
} }
} else {
strncpy (ncs, connstring, sizeof (nfc_connstring));
} }
if (pndd == NULL)
return NULL;
log_init ();
// Search through the device list for an available device // Search through the device list for an available device
const struct nfc_driver_t *ndr; const struct nfc_driver_t *ndr;
const struct nfc_driver_t **pndr = nfc_drivers; const struct nfc_driver_t **pndr = nfc_drivers;
while ((ndr = *pndr)) { while ((ndr = *pndr)) {
// Specific device is requested: using device description pndd // Specific device is requested: using device description
if (0 != strcmp (ndr->name, pndd->pcDriver)) { if (0 != strncmp (ndr->name, ncs, strlen(ndr->name))) {
pndr++; pndr++;
continue; continue;
} else {
pnd = ndr->connect (pndd);
} }
pnd = ndr->connect (ncs);
// Test if the connection was successful // Test if the connection was successful
if (pnd != NULL) { if (pnd == NULL) {
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "[%s] has been claimed.", pnd->acName); log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "Unable to connect to \"%s\".", ncs);
log_fini ();
return pnd; return pnd;
} else {
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "No device found using driver: %s", ndr->name);
} }
pndr++;
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "[%s] has been claimed.", pnd->acName);
log_fini ();
return pnd;
} }
// Too bad, no driver can decode connstring
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "No driver available to handle \"%s\".", ncs);
log_fini (); log_fini ();
// Too bad, no reader is ready to be claimed
return NULL; return NULL;
} }
@ -147,7 +182,7 @@ nfc_disconnect (nfc_device_t * pnd)
* @param[out] pszDeviceFound number of devices found. * @param[out] pszDeviceFound number of devices found.
*/ */
void void
nfc_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound) nfc_list_devices (nfc_connstring connstrings[] , size_t szDevices, size_t * pszDeviceFound)
{ {
size_t szN; size_t szN;
*pszDeviceFound = 0; *pszDeviceFound = 0;
@ -157,7 +192,7 @@ nfc_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps
log_init (); log_init ();
while ((ndr = *pndr)) { while ((ndr = *pndr)) {
szN = 0; szN = 0;
if (ndr->probe (pnddDevices + (*pszDeviceFound), szDevices - (*pszDeviceFound), &szN)) { if (ndr->probe (connstrings + (*pszDeviceFound), szDevices - (*pszDeviceFound), &szN)) {
*pszDeviceFound += szN; *pszDeviceFound += szN;
log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%ld device(s) found using %s driver", (unsigned long) szN, ndr->name); log_put (LOG_CATEGORY, NFC_PRIORITY_TRACE, "%ld device(s) found using %s driver", (unsigned long) szN, ndr->name);
if (*pszDeviceFound == szDevices) if (*pszDeviceFound == szDevices)

View file

@ -62,18 +62,16 @@ static nfc_device_t *pnd;
int int
main (int argc, const char *argv[]) main (int argc, const char *argv[])
{ {
(void) argc;
const char *acLibnfcVersion; const char *acLibnfcVersion;
size_t szDeviceFound;
size_t szTargetFound; size_t szTargetFound;
size_t i; size_t i;
bool verbose = false; bool verbose = false;
nfc_device_desc_t *pnddDevices;
// Display libnfc version // Display libnfc version
acLibnfcVersion = nfc_version (); acLibnfcVersion = nfc_version ();
printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion); printf ("%s uses libnfc %s\n", argv[0], acLibnfcVersion);
pnddDevices = parse_args (argc, argv, &szDeviceFound, &verbose);
#ifdef HAVE_LIBUSB #ifdef HAVE_LIBUSB
# ifdef DEBUG # ifdef DEBUG
usb_set_debug (4); usb_set_debug (4);
@ -101,15 +99,9 @@ main (int argc, const char *argv[])
strcpy(ndd.acDevice, "SCM Micro / SCL3711-NFC&RW"); strcpy(ndd.acDevice, "SCM Micro / SCL3711-NFC&RW");
pnd = nfc_connect (&ndd); pnd = nfc_connect (&ndd);
#endif #endif
size_t szDeviceFound;
if (szDeviceFound == 0) { nfc_connstring connstrings[MAX_DEVICE_COUNT];
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) { nfc_list_devices (connstrings, MAX_DEVICE_COUNT, &szDeviceFound);
fprintf (stderr, "malloc() failed\n");
return EXIT_FAILURE;
}
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szDeviceFound);
}
if (szDeviceFound == 0) { if (szDeviceFound == 0) {
printf ("No NFC device found.\n"); printf ("No NFC device found.\n");
@ -117,7 +109,7 @@ main (int argc, const char *argv[])
for (i = 0; i < szDeviceFound; i++) { for (i = 0; i < szDeviceFound; i++) {
nfc_target_t ant[MAX_TARGET_COUNT]; nfc_target_t ant[MAX_TARGET_COUNT];
pnd = nfc_connect (&(pnddDevices[i])); pnd = nfc_connect (connstrings[i]);
if (pnd == NULL) { if (pnd == NULL) {
ERR ("%s", "Unable to connect to NFC device."); ERR ("%s", "Unable to connect to NFC device.");
@ -243,6 +235,5 @@ main (int argc, const char *argv[])
nfc_disconnect (pnd); nfc_disconnect (pnd);
} }
free (pnddDevices);
return 0; return 0;
} }

View file

@ -150,7 +150,6 @@ main (int argc, char *argv[])
{ {
int arg; int arg;
size_t szFound; size_t szFound;
nfc_device_desc_t *pnddDevices;
const char *acLibnfcVersion = nfc_version (); const char *acLibnfcVersion = nfc_version ();
nfc_target_t ntRealTarget; nfc_target_t ntRealTarget;
@ -192,13 +191,9 @@ main (int argc, char *argv[])
signal (SIGINT, (void (*)()) intr_hdlr); signal (SIGINT, (void (*)()) intr_hdlr);
#endif #endif
// Allocate memory to put the result of available devices listing nfc_connstring connstrings[MAX_DEVICE_COUNT];
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
fprintf (stderr, "malloc() failed\n");
return EXIT_FAILURE;
}
// List available devices // List available devices
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound); nfc_list_devices (connstrings, MAX_DEVICE_COUNT, &szFound);
if (initiator_only_mode || target_only_mode) { if (initiator_only_mode || target_only_mode) {
if (szFound < 1) { if (szFound < 1) {
@ -222,9 +217,9 @@ main (int argc, char *argv[])
// if there is more than one readers connected we connect to the second reader // if there is more than one readers connected we connect to the second reader
// (we hope they're always detected in the same order) // (we hope they're always detected in the same order)
if (szFound == 1) { if (szFound == 1) {
pndInitiator = nfc_connect (&(pnddDevices[0])); pndInitiator = nfc_connect (connstrings[0]);
} else { } else {
pndInitiator = nfc_connect (&(pnddDevices[1])); pndInitiator = nfc_connect (connstrings[1]);
} }
if (!pndInitiator) { if (!pndInitiator) {
@ -348,7 +343,7 @@ main (int argc, char *argv[])
print_nfc_iso14443a_info (ntEmulatedTarget.nti.nai, false); print_nfc_iso14443a_info (ntEmulatedTarget.nti.nai, false);
// Try to open the NFC emulator device // Try to open the NFC emulator device
pndTarget = nfc_connect (&(pnddDevices[0])); pndTarget = nfc_connect (connstrings[0]);
if (pndTarget == NULL) { if (pndTarget == NULL) {
printf ("Error connecting NFC emulator device\n"); printf ("Error connecting NFC emulator device\n");
if (!target_only_mode) { if (!target_only_mode) {

View file

@ -670,51 +670,6 @@ print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose)
} }
} }
/**
* @brief Tries to parse arguments to find device descriptions.
* @return Returns the list of found device descriptions.
*/
nfc_device_desc_t *
parse_args (int argc, const char *argv[], size_t * szFound, bool * verbose)
{
nfc_device_desc_t *pndd = 0;
int arg;
*szFound = 0;
// Get commandline options
for (arg = 1; arg < argc; arg++) {
if (0 == strcmp (argv[arg], "--device")) {
// FIXME: this device selection by command line options is terrible & does not support USB/PCSC drivers
if (argc > arg + 1) {
char buffer[256];
pndd = malloc (sizeof (nfc_device_desc_t));
strncpy (buffer, argv[++arg], 256);
// Driver.
pndd->pcDriver = (char *) malloc (256);
strcpy (pndd->pcDriver, strtok (buffer, ":"));
// Port.
strcpy (pndd->acPort, strtok (NULL, ":"));
// Speed.
sscanf (strtok (NULL, ":"), "%u", &pndd->uiSpeed);
*szFound = 1;
} else {
errx (1, "usage: %s [--device driver:port:speed]", argv[0]);
}
}
if ((0 == strcmp (argv[arg], "-v")) || (0 == strcmp (argv[arg], "--verbose"))) {
*verbose = true;
}
}
return pndd;
}
const char * const char *
str_nfc_baud_rate (const nfc_baud_rate_t nbr) str_nfc_baud_rate (const nfc_baud_rate_t nbr)
{ {

View file

@ -97,6 +97,4 @@ void print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose);
void print_nfc_target (const nfc_target_t nt, bool verbose); void print_nfc_target (const nfc_target_t nt, bool verbose);
nfc_device_desc_t *parse_args (int argc, const char *argv[], size_t * szFound, bool * verbose);
#endif #endif