ACR122 devices support enhancements.
- Add driver agnostic nfc_pick_device(), nfc_list_devices(); - New API function: nfc_list_devices(); - PCSC Context sharing for acr122 driver; - List all devices in nfc-list(1); - Various code fixes and cleanup; - Remove warnings when compiling; - Merge r191:199 from trunk \_°< Coin!
This commit is contained in:
parent
1af29561e8
commit
220bef3490
20 changed files with 248 additions and 94 deletions
|
@ -3,7 +3,7 @@ SUBDIRS = src
|
|||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libnfc.pc
|
||||
|
||||
EXTRA_DIST = Doxyfile
|
||||
EXTRA_DIST = Doxyfile pn53x.rules
|
||||
CLEANFILES = Doxygen.log
|
||||
|
||||
if DOC_ENABLED
|
||||
|
|
2
README
2
README
|
@ -17,7 +17,7 @@ http://www.libnfc.org/community
|
|||
------------------------------------------------------------------------
|
||||
Proprietary Notes:
|
||||
|
||||
FeliCa is s registered trademark of Sony Corporation. MIFARE is a
|
||||
FeliCa is s registered trademark of the Sony Corporation. MIFARE is a
|
||||
trademark of NXP Semiconductors. Jewel Topaz is a trademark of Innovision
|
||||
Research & Technology. All other trademarks are the property of their
|
||||
respective owners.
|
||||
|
|
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -1,3 +1,9 @@
|
|||
libnfc (1.2.1-4) unstable; urgency=low
|
||||
|
||||
* Add udev rules for USB PN53x.
|
||||
|
||||
-- Romuald Conty <rconty@il4p.fr> Fri, 20 Nov 2009 16:42:42 +0100
|
||||
|
||||
libnfc (1.2.1-3) unstable; urgency=low
|
||||
|
||||
* Don't use CDBS anymore, should now cross compile.
|
||||
|
|
1
debian/libnfc0.install
vendored
1
debian/libnfc0.install
vendored
|
@ -1 +1,2 @@
|
|||
debian/tmp/usr/lib/libnfc.so.*
|
||||
pn53x.rules etc/udev/rules.d/
|
||||
|
|
15
pn53x.rules
Normal file
15
pn53x.rules
Normal file
|
@ -0,0 +1,15 @@
|
|||
# udev rules file for PN531 and PN533 devices (for udev 0.98 version)
|
||||
# to be installed in /etc/udev/rules.d
|
||||
|
||||
SUBSYSTEM!="usb|usb_device", GOTO="pn53x_rules_end"
|
||||
ACTION!="add", GOTO="pn53x_rules_end"
|
||||
|
||||
# PN531
|
||||
ATTRS{idVendor}=="04cc", ATTRS{idProduct}=="0531", MODE="0664", GROUP="plugdev"
|
||||
ATTRS{idVendor}=="054c", ATTRS{idProduct}=="0193", MODE="0664", GROUP="plugdev"
|
||||
|
||||
# PN533
|
||||
ATTRS{idVendor}=="04cc", ATTRS{idProduct}=="2533", MODE="0664", GROUP="plugdev"
|
||||
ATTRS{idVendor}=="04e6", ATTRS{idProduct}=="5591", MODE="0664", GROUP="plugdev"
|
||||
|
||||
LABEL="pn53x_rules_end"
|
|
@ -32,18 +32,26 @@
|
|||
#include "nfc-messages.h"
|
||||
#include "bitutils.h"
|
||||
|
||||
#define MAX_DEVICE_COUNT 16
|
||||
|
||||
static nfc_device_t* pnd;
|
||||
static byte_t abtFelica[5] = { 0x00, 0xff, 0xff, 0x00, 0x00 };
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
size_t szFound;
|
||||
int i;
|
||||
nfc_target_info_t nti;
|
||||
nfc_device_desc_t *pnddDevices;
|
||||
|
||||
// Display libnfc version
|
||||
const char* acLibnfcVersion = nfc_version();
|
||||
printf("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||
|
||||
// Try to open the NFC device
|
||||
// Lazy way to open an NFC device
|
||||
/*
|
||||
pnd = nfc_connect(NULL);
|
||||
*/
|
||||
|
||||
// If specific device is wanted, i.e. an ARYGON device on /dev/ttyUSB0
|
||||
/*
|
||||
|
@ -54,10 +62,27 @@ int main(int argc, const char* argv[])
|
|||
|
||||
pnd = nfc_connect(&ndd);
|
||||
*/
|
||||
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices))))
|
||||
{
|
||||
fprintf (stderr, "malloc() failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound);
|
||||
|
||||
if (szFound == 0)
|
||||
{
|
||||
INFO("%s", "No device found.");
|
||||
}
|
||||
|
||||
for (i = 0; i < szFound; i++)
|
||||
{
|
||||
pnd = nfc_connect(&(pnddDevices[i]));
|
||||
|
||||
|
||||
if (pnd == NULL)
|
||||
{
|
||||
ERR("Unable to connect to NFC device.");
|
||||
ERR("%s", "Unable to connect to NFC device.");
|
||||
return 1;
|
||||
}
|
||||
nfc_initiator_init(pnd);
|
||||
|
@ -121,5 +146,8 @@ int main(int argc, const char* argv[])
|
|||
}
|
||||
|
||||
nfc_disconnect(pnd);
|
||||
}
|
||||
|
||||
free (pnddDevices);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <nfc.h>
|
||||
|
||||
|
@ -41,6 +42,14 @@ static byte_t abtTagRxPar[MAX_FRAME_LEN];
|
|||
static size_t szTagRxBits;
|
||||
static nfc_device_t* pndReader;
|
||||
static nfc_device_t* pndTag;
|
||||
static bool quitting=false;
|
||||
|
||||
void intr_hdlr(void)
|
||||
{
|
||||
printf("\nQuitting...\n");
|
||||
quitting=true;
|
||||
return;
|
||||
}
|
||||
|
||||
void print_usage(char* argv[])
|
||||
{
|
||||
|
@ -70,6 +79,12 @@ int main(int argc,char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
signal(SIGINT, (void (__cdecl*)(int)) intr_hdlr);
|
||||
#else
|
||||
signal(SIGINT, (void (*)()) intr_hdlr);
|
||||
#endif
|
||||
|
||||
// Try to open the NFC emulator device
|
||||
pndTag = nfc_connect(NULL);
|
||||
if (pndTag == NULL)
|
||||
|
@ -83,7 +98,12 @@ int main(int argc,char* argv[])
|
|||
printf("[+] Try to break out the auto-emulation, this requires a second reader!\n");
|
||||
printf("[+] To do this, please send any command after the anti-collision\n");
|
||||
printf("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
|
||||
nfc_target_init(pndTag,abtReaderRx,&szReaderRxBits);
|
||||
if (!nfc_target_init(pndTag,abtReaderRx,&szReaderRxBits))
|
||||
{
|
||||
printf("[+] Initialization of NFC emulator failed\n");
|
||||
nfc_disconnect(pndTag);
|
||||
return 1;
|
||||
}
|
||||
printf("[+] Configuring emulator settings\n");
|
||||
nfc_configure(pndTag,NDO_HANDLE_CRC,false);
|
||||
nfc_configure(pndTag,NDO_HANDLE_PARITY,false);
|
||||
|
@ -94,12 +114,13 @@ int main(int argc,char* argv[])
|
|||
pndReader = NULL;
|
||||
while (pndReader == NULL) pndReader = nfc_connect(NULL);
|
||||
printf("[+] Configuring NFC reader settings\n");
|
||||
nfc_initiator_init(pndReader);
|
||||
nfc_configure(pndReader,NDO_HANDLE_CRC,false);
|
||||
nfc_configure(pndReader,NDO_HANDLE_PARITY,false);
|
||||
nfc_configure(pndReader,NDO_ACCEPT_INVALID_FRAMES,true);
|
||||
printf("[+] Done, relaying frames now!\n\n");
|
||||
|
||||
while(true)
|
||||
while(!quitting)
|
||||
{
|
||||
// Test if we received a frame from the reader
|
||||
if (nfc_target_receive_bits(pndTag,abtReaderRx,&szReaderRxBits,abtReaderRxPar))
|
||||
|
|
|
@ -160,8 +160,14 @@ void print_hex_bits(const byte_t* pbtData, const size_t szBits)
|
|||
printf("%02x ",pbtData[szPos]);
|
||||
}
|
||||
|
||||
// Print the rest bits, these cannot have no parity bit
|
||||
if (szBits%8 != 0) printf("%02x",pbtData[szBytes]);
|
||||
// Print the rest bits
|
||||
if (szBits%8 != 0)
|
||||
{
|
||||
if (szBits%8 < 5)
|
||||
printf("%01x (%i bits)",pbtData[szBytes], szBits%8);
|
||||
else
|
||||
printf("%02x (%i bits)",pbtData[szBytes], szBits%8);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
@ -182,8 +188,14 @@ void print_hex_par(const byte_t* pbtData, const size_t szBits, const byte_t* pbt
|
|||
}
|
||||
}
|
||||
|
||||
// Print the rest bits, these cannot have no parity bit
|
||||
if (szBits%8 != 0) printf("%02x",pbtData[szBytes]);
|
||||
// Print the rest bits, these cannot have parity bit
|
||||
if (szBits%8 != 0)
|
||||
{
|
||||
if (szBits%8 < 5)
|
||||
printf("%01x (%i bits)",pbtData[szBytes], szBits%8);
|
||||
else
|
||||
printf("%02x (%i bits)",pbtData[szBytes], szBits%8);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
|||
cfsetospeed((struct termios*)&spu->tiNew, stPortSpeed);
|
||||
if( tcsetattr(spu->fd, TCSADRAIN, &spu->tiNew) == -1)
|
||||
{
|
||||
ERR("Unable to apply new speed settings.");
|
||||
ERR("%s", "Unable to apply new speed settings.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,7 +195,7 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
|||
|
||||
// Read error
|
||||
if (res < 0) {
|
||||
DBG("RX error.");
|
||||
DBG("%s", "RX error.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
|||
if (res == 0) {
|
||||
if (*pszRxLen == 0) {
|
||||
// Error, we received no data
|
||||
DBG("RX time-out, buffer empty.");
|
||||
DBG("%s", "RX time-out, buffer empty.");
|
||||
return false;
|
||||
} else {
|
||||
// We received some data, but nothing more is available
|
||||
|
@ -245,13 +245,13 @@ bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
|||
|
||||
// Write error
|
||||
if (res < 0) {
|
||||
DBG("TX error.");
|
||||
DBG("%s", "TX error.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write time-out
|
||||
if (res == 0) {
|
||||
DBG("TX time-out.");
|
||||
DBG("%s", "TX time-out.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
* @brief PN531, PN532 and PN533 common functions
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pn53x.h"
|
||||
|
|
|
@ -42,16 +42,16 @@
|
|||
#define MAX_FRAME_LEN 264
|
||||
|
||||
const static struct driver_callbacks drivers_callbacks_list[] = {
|
||||
// Driver Name List Devices Connect Transceive Disconnect
|
||||
// Driver Name Pick Device List Devices Connect Transceive Disconnect
|
||||
#ifdef HAVE_PCSC_LITE
|
||||
{ ACR122_DRIVER_NAME, acr122_list_devices, acr122_connect, acr122_transceive, acr122_disconnect },
|
||||
{ ACR122_DRIVER_NAME, acr122_pick_device, acr122_list_devices, acr122_connect, acr122_transceive, acr122_disconnect },
|
||||
#endif /* HAVE_PCSC_LITE */
|
||||
#ifdef HAVE_LIBUSB
|
||||
{ PN531_USB_DRIVER_NAME, NULL, pn531_usb_connect, pn531_usb_transceive, pn531_usb_disconnect },
|
||||
{ PN533_USB_DRIVER_NAME, NULL, pn533_usb_connect, pn533_usb_transceive, pn533_usb_disconnect },
|
||||
{ PN531_USB_DRIVER_NAME, NULL, NULL, pn531_usb_connect, pn531_usb_transceive, pn531_usb_disconnect },
|
||||
{ PN533_USB_DRIVER_NAME, NULL, NULL, pn533_usb_connect, pn533_usb_transceive, pn533_usb_disconnect },
|
||||
#endif /* HAVE_LIBUSB */
|
||||
{ PN532_UART_DRIVER_NAME, NULL, pn532_uart_connect, pn532_uart_transceive, pn532_uart_disconnect },
|
||||
{ ARYGON_DRIVER_NAME, NULL, arygon_connect, arygon_transceive, arygon_disconnect }
|
||||
{ PN532_UART_DRIVER_NAME, NULL, NULL, pn532_uart_connect, pn532_uart_transceive, pn532_uart_disconnect },
|
||||
{ ARYGON_DRIVER_NAME, NULL, NULL, arygon_connect, arygon_transceive, arygon_disconnect }
|
||||
};
|
||||
|
||||
#endif // __NFC_DRIVERS_H__
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "acr122.h"
|
||||
#include "../drivers.h"
|
||||
|
||||
#include "../bitutils.h"
|
||||
|
||||
// Bus
|
||||
#include <winscard.h>
|
||||
|
@ -55,12 +55,41 @@
|
|||
#define ACR122_COMMAND_LEN 266
|
||||
#define ACR122_RESPONSE_LEN 268
|
||||
|
||||
|
||||
typedef struct {
|
||||
SCARDCONTEXT hCtx;
|
||||
SCARDHANDLE hCard;
|
||||
SCARD_IO_REQUEST ioCard;
|
||||
} acr122_spec_t;
|
||||
|
||||
static SCARDCONTEXT _SCardContext;
|
||||
static int _iSCardContextRefCount = 0;
|
||||
|
||||
SCARDCONTEXT*
|
||||
acr122_get_scardcontext(void)
|
||||
{
|
||||
if ( _iSCardContextRefCount == 0 )
|
||||
{
|
||||
if (SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&_SCardContext) != SCARD_S_SUCCESS) return NULL;
|
||||
}
|
||||
_iSCardContextRefCount++;
|
||||
|
||||
return &_SCardContext;
|
||||
}
|
||||
|
||||
void
|
||||
acr122_free_scardcontext(void)
|
||||
{
|
||||
if (_iSCardContextRefCount)
|
||||
{
|
||||
_iSCardContextRefCount--;
|
||||
if (!_iSCardContextRefCount)
|
||||
{
|
||||
SCardReleaseContext(_SCardContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nfc_device_desc_t *
|
||||
acr122_pick_device (void)
|
||||
{
|
||||
|
@ -69,13 +98,13 @@ acr122_pick_device (void)
|
|||
if ((pndd = malloc (sizeof (*pndd)))) {
|
||||
size_t szN;
|
||||
|
||||
if (!acr122_list_devices (&pndd, 1, &szN)) {
|
||||
ERR("acr122_list_devices failed");
|
||||
if (!acr122_list_devices (pndd, 1, &szN)) {
|
||||
ERR("%s", "acr122_list_devices failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (szN == 0) {
|
||||
ERR("No device found");
|
||||
ERR("%s", "No device found");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +113,7 @@ acr122_pick_device (void)
|
|||
}
|
||||
|
||||
/**
|
||||
* @fn bool acr122_list_devices(nfc_device_desc_t *pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
* @fn bool acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
* @brief List connected devices
|
||||
*
|
||||
* Probe PCSC to find NFC capable hardware.
|
||||
|
@ -95,7 +124,7 @@ acr122_pick_device (void)
|
|||
* @return true if succeeded, false otherwise.
|
||||
*/
|
||||
bool
|
||||
acr122_list_devices(nfc_device_desc_t *pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
{
|
||||
size_t szPos = 0;
|
||||
char acDeviceNames[256+64*DRIVERS_MAX_DEVICES];
|
||||
|
@ -103,6 +132,7 @@ acr122_list_devices(nfc_device_desc_t *pnddDevices[], size_t szDevices, size_t *
|
|||
acr122_spec_t as;
|
||||
uint32_t uiBusIndex = 0;
|
||||
char *pcFirmware;
|
||||
SCARDCONTEXT *pscc;
|
||||
|
||||
// Clear the reader list
|
||||
memset(acDeviceNames, '\0', szDeviceNamesLen);
|
||||
|
@ -110,12 +140,13 @@ acr122_list_devices(nfc_device_desc_t *pnddDevices[], size_t szDevices, size_t *
|
|||
*pszDeviceFound = 0;
|
||||
|
||||
// Test if context succeeded
|
||||
if (SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&(as.hCtx)) != SCARD_S_SUCCESS) return false;
|
||||
if (!(pscc = acr122_get_scardcontext ())) return false;
|
||||
//if (SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&(pscc)) != SCARD_S_SUCCESS) return false;
|
||||
|
||||
// Retrieve the string array of all available pcsc readers
|
||||
if (SCardListReaders(as.hCtx,NULL,acDeviceNames,(void*)&szDeviceNamesLen) != SCARD_S_SUCCESS) return false;
|
||||
if (SCardListReaders(*pscc,NULL,acDeviceNames,(void*)&szDeviceNamesLen) != SCARD_S_SUCCESS) return false;
|
||||
|
||||
DBG("PCSC reports following device(s):");
|
||||
DBG("%s", "PCSC reports following device(s):");
|
||||
|
||||
while ((acDeviceNames[szPos] != '\0') && ((*pszDeviceFound) < szDevices)) {
|
||||
uiBusIndex++;
|
||||
|
@ -123,7 +154,7 @@ acr122_list_devices(nfc_device_desc_t *pnddDevices[], size_t szDevices, size_t *
|
|||
DBG("- %s (pos=%d)", acDeviceNames + szPos, szPos);
|
||||
|
||||
// Test if we were able to connect to the "emulator" card
|
||||
if (SCardConnect(as.hCtx,acDeviceNames + szPos,SCARD_SHARE_EXCLUSIVE,SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,&(as.hCard),(void*)&(as.ioCard.dwProtocol)) == SCARD_S_SUCCESS)
|
||||
if (SCardConnect(*pscc,acDeviceNames + szPos,SCARD_SHARE_EXCLUSIVE,SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,&(as.hCard),(void*)&(as.ioCard.dwProtocol)) == SCARD_S_SUCCESS)
|
||||
{
|
||||
// Configure I/O settings for card communication
|
||||
as.ioCard.cbPciLength = sizeof(SCARD_IO_REQUEST);
|
||||
|
@ -133,31 +164,31 @@ acr122_list_devices(nfc_device_desc_t *pnddDevices[], size_t szDevices, size_t *
|
|||
if (strstr(pcFirmware,FIRMWARE_TEXT) != NULL)
|
||||
{
|
||||
// Supported ACR122 device found
|
||||
strncpy(pnddDevices[*pszDeviceFound]->acDevice, acDeviceNames + szPos, BUFSIZ - 1);
|
||||
pnddDevices[*pszDeviceFound]->acDevice[BUFSIZ - 1] = '\0';
|
||||
pnddDevices[*pszDeviceFound]->pcDriver = ACR122_DRIVER_NAME;
|
||||
pnddDevices[*pszDeviceFound]->uiBusIndex = uiBusIndex;
|
||||
strncpy(pnddDevices[*pszDeviceFound].acDevice, acDeviceNames + szPos, BUFSIZ - 1);
|
||||
pnddDevices[*pszDeviceFound].acDevice[BUFSIZ - 1] = '\0';
|
||||
pnddDevices[*pszDeviceFound].pcDriver = ACR122_DRIVER_NAME;
|
||||
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
|
||||
(*pszDeviceFound)++;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG("Firmware version mismatch");
|
||||
DBG("%s", "Firmware version mismatch");
|
||||
}
|
||||
SCardDisconnect(as.hCard,SCARD_LEAVE_CARD);
|
||||
SCardReleaseContext(as.hCtx);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG("Can't contact emulator card");
|
||||
DBG("%s", "Can't contact emulator card");
|
||||
}
|
||||
|
||||
// Find next device name position
|
||||
while (acDeviceNames[szPos++] != '\0');
|
||||
}
|
||||
acr122_free_scardcontext ();
|
||||
//SCardReleaseContext(pscc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd)
|
||||
{
|
||||
nfc_device_t* pnd = NULL;
|
||||
|
@ -165,32 +196,19 @@ nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd)
|
|||
acr122_spec_t* pas;
|
||||
char* pcFirmware;
|
||||
|
||||
bool bPnddLocallyAllocated = false;
|
||||
|
||||
// If no description is provided, pick a device automagically.
|
||||
if (pndd == NULL)
|
||||
{
|
||||
pndd = acr122_pick_device();
|
||||
if (pndd == NULL) return NULL;
|
||||
|
||||
bPnddLocallyAllocated = true;
|
||||
}
|
||||
SCARDCONTEXT *pscc;
|
||||
|
||||
// Test if context succeeded
|
||||
if (SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&(as.hCtx)) != SCARD_S_SUCCESS)
|
||||
{
|
||||
if (bPnddLocallyAllocated == true) free (pndd);
|
||||
return NULL;
|
||||
}
|
||||
if (!(pscc = acr122_get_scardcontext ())) return NULL;
|
||||
//if (SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&(pscc)) != SCARD_S_SUCCESS) return NULL;
|
||||
|
||||
// Test if we were able to connect to the "emulator" card
|
||||
if (SCardConnect(as.hCtx,pndd->acDevice,SCARD_SHARE_EXCLUSIVE,SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,&(as.hCard),(void*)&(as.ioCard.dwProtocol)) != SCARD_S_SUCCESS)
|
||||
if (SCardConnect(*pscc,pndd->acDevice,SCARD_SHARE_EXCLUSIVE,SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,&(as.hCard),(void*)&(as.ioCard.dwProtocol)) != SCARD_S_SUCCESS)
|
||||
{
|
||||
// Connect to ACR122 firmware version >2.0
|
||||
if (SCardConnect(as.hCtx,pndd->acDevice,SCARD_SHARE_DIRECT,0,&(as.hCard),(void*)&(as.ioCard.dwProtocol)) != SCARD_S_SUCCESS)
|
||||
if (SCardConnect(*pscc,pndd->acDevice,SCARD_SHARE_DIRECT,0,&(as.hCard),(void*)&(as.ioCard.dwProtocol)) != SCARD_S_SUCCESS)
|
||||
{
|
||||
// We can not connect to this device.
|
||||
if (bPnddLocallyAllocated == true) free (pndd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -215,18 +233,17 @@ nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd)
|
|||
pnd->bCrc = true;
|
||||
pnd->bPar = true;
|
||||
pnd->ui8TxBits = 0;
|
||||
return pnd;
|
||||
}
|
||||
|
||||
if (bPnddLocallyAllocated == true) free (pndd);
|
||||
|
||||
return pnd;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void acr122_disconnect(nfc_device_t* pnd)
|
||||
{
|
||||
acr122_spec_t* pas = (acr122_spec_t*)pnd->nds;
|
||||
SCardDisconnect(pas->hCard,SCARD_LEAVE_CARD);
|
||||
SCardReleaseContext(pas->hCtx);
|
||||
acr122_free_scardcontext ();
|
||||
free(pas);
|
||||
free(pnd);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#define ACR122_DRIVER_NAME "ACR122"
|
||||
|
||||
nfc_device_desc_t* acr122_pick_device(void);
|
||||
bool acr122_list_devices(nfc_device_desc_t *pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
bool acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
|
||||
// Functions used by developer to handle connection to this device
|
||||
nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd);
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
* @file arygon.c
|
||||
* @brief
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
|
||||
#include "arygon.h"
|
||||
|
@ -28,6 +28,7 @@
|
|||
#include "nfc-messages.h"
|
||||
|
||||
#include "../drivers.h"
|
||||
#include "../bitutils.h"
|
||||
// Bus
|
||||
#include "uart.h"
|
||||
|
||||
|
@ -173,7 +174,7 @@ bool arygon_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const s
|
|||
print_hex(abtTxBuf,szTxLen+8);
|
||||
#endif
|
||||
if (!uart_send((serial_port)nds,abtTxBuf,szTxLen+8)) {
|
||||
ERR("Unable to transmit data. (TX)");
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -193,7 +194,7 @@ bool arygon_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const s
|
|||
*/
|
||||
|
||||
if (!uart_receive((serial_port)nds,abtRxBuf,&szRxBufLen)) {
|
||||
ERR("Unable to receive data. (RX)");
|
||||
ERR("%s", "Unable to receive data. (RX)");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,14 +28,13 @@ Thanks to d18c7db and Okko for example code
|
|||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <usb.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pn531_usb.h"
|
||||
#include "../drivers.h"
|
||||
|
||||
// Bus
|
||||
#include <usb.h>
|
||||
|
||||
#include "nfc-messages.h"
|
||||
#include "../bitutils.h"
|
||||
|
||||
|
@ -129,7 +128,7 @@ nfc_device_t* pn531_usb_connect(const nfc_device_desc_t* pndd)
|
|||
uiDevIndex--;
|
||||
continue;
|
||||
}
|
||||
DBG("Found PN531 device");
|
||||
DBG("%s", "Found PN531 device");
|
||||
|
||||
// Open the PN531 USB device
|
||||
us.pudh = usb_open(dev);
|
||||
|
@ -137,16 +136,17 @@ nfc_device_t* pn531_usb_connect(const nfc_device_desc_t* pndd)
|
|||
get_end_points(dev,&us);
|
||||
if(usb_set_configuration(us.pudh,1) < 0)
|
||||
{
|
||||
DBG("Set config failed");
|
||||
DBG("%s", "Set config failed");
|
||||
usb_close(us.pudh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(usb_claim_interface(us.pudh,0) < 0)
|
||||
{
|
||||
DBG("Can't claim interface");
|
||||
DBG("%s", "Can't claim interface");
|
||||
usb_close(us.pudh);
|
||||
return NULL;
|
||||
// don't return yet as there might be other readers on USB bus
|
||||
continue;
|
||||
}
|
||||
// Allocate memory for the device info and specification, fill it and return the info
|
||||
pus = malloc(sizeof(usb_spec_t));
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
* @file pn532_uart.c
|
||||
* @brief
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pn532_uart.h"
|
||||
|
@ -28,6 +28,7 @@
|
|||
#include "nfc-messages.h"
|
||||
|
||||
#include "../drivers.h"
|
||||
#include "../bitutils.h"
|
||||
|
||||
// Bus
|
||||
#include "uart.h"
|
||||
|
@ -109,7 +110,7 @@ nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
|||
delay_ms(10);
|
||||
|
||||
if (!uart_receive(sp,abtRxBuf,&szRxBufLen)) {
|
||||
ERR("Unable to receive data. (RX)");
|
||||
ERR("%s", "Unable to receive data. (RX)");
|
||||
return NULL;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
|
@ -166,7 +167,7 @@ bool pn532_uart_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, con
|
|||
print_hex(abtTxBuf,szTxLen+7);
|
||||
#endif
|
||||
if (!uart_send((serial_port)nds,abtTxBuf,szTxLen+7)) {
|
||||
ERR("Unable to transmit data. (TX)");
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -181,7 +182,7 @@ bool pn532_uart_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, con
|
|||
delay_ms(30);
|
||||
|
||||
if (!uart_receive((serial_port)nds,abtRxBuf,&szRxBufLen)) {
|
||||
ERR("Unable to receive data. (RX)");
|
||||
ERR("%s", "Unable to receive data. (RX)");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,14 +27,12 @@ Thanks to d18c7db and Okko for example code
|
|||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <usb.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pn533_usb.h"
|
||||
#include "../drivers.h"
|
||||
|
||||
// Bus
|
||||
#include <usb.h>
|
||||
|
||||
#include "nfc-messages.h"
|
||||
|
||||
#define BUFFER_LENGTH 256
|
||||
|
@ -124,7 +122,7 @@ nfc_device_t* pn533_usb_connect(const nfc_device_desc_t* pndd)
|
|||
uiDevIndex--;
|
||||
continue;
|
||||
}
|
||||
DBG("Found PN533 device");
|
||||
DBG("%s", "Found PN533 device");
|
||||
|
||||
// Open the PN533 USB device
|
||||
us.pudh = usb_open(dev);
|
||||
|
@ -132,16 +130,17 @@ nfc_device_t* pn533_usb_connect(const nfc_device_desc_t* pndd)
|
|||
get_end_points(dev,&us);
|
||||
if(usb_set_configuration(us.pudh,1) < 0)
|
||||
{
|
||||
DBG("Setting config failed");
|
||||
DBG("%s", "Setting config failed");
|
||||
usb_close(us.pudh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(usb_claim_interface(us.pudh,0) < 0)
|
||||
{
|
||||
DBG("Can't claim interface");
|
||||
DBG("%s", "Can't claim interface");
|
||||
usb_close(us.pudh);
|
||||
return NULL;
|
||||
// don't return yet as there might be other readers on USB bus
|
||||
continue;
|
||||
}
|
||||
// Allocate memory for the device info and specification, fill it and return the info
|
||||
pus = malloc(sizeof(usb_spec_t));
|
||||
|
|
|
@ -97,8 +97,10 @@ typedef struct {
|
|||
struct driver_callbacks {
|
||||
/** Driver name */
|
||||
const char* acDriver;
|
||||
/** Pick devices callback */
|
||||
nfc_device_desc_t *(*pick_device)(void);
|
||||
/** List devices callback */
|
||||
bool (*list_devices)(nfc_device_desc_t *pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
bool (*list_devices)(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
/** Connect callback */
|
||||
nfc_device_t* (*connect)(const nfc_device_desc_t* pndd);
|
||||
/** Transceive callback */
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
|
||||
#include "../../config.h"
|
||||
|
||||
nfc_device_desc_t * nfc_pick_device (void);
|
||||
|
||||
// PN53X configuration
|
||||
extern const byte_t pncmd_get_firmware_version [ 2];
|
||||
extern const byte_t pncmd_get_general_status [ 2];
|
||||
|
@ -63,28 +65,67 @@ extern const byte_t pncmd_target_receive [ 2];
|
|||
extern const byte_t pncmd_target_send [264];
|
||||
extern const byte_t pncmd_target_get_status [ 2];
|
||||
|
||||
nfc_device_desc_t *
|
||||
nfc_pick_device (void)
|
||||
{
|
||||
uint32_t uiDriver;
|
||||
nfc_device_desc_t *nddRes;
|
||||
|
||||
for (uiDriver=0; uiDriver<sizeof(drivers_callbacks_list)/sizeof(drivers_callbacks_list[0]); uiDriver++)
|
||||
{
|
||||
if (drivers_callbacks_list[uiDriver].pick_device != NULL)
|
||||
{
|
||||
nddRes = drivers_callbacks_list[uiDriver].pick_device ();
|
||||
if (nddRes != NULL) return nddRes;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
nfc_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
{
|
||||
uint32_t uiDriver;
|
||||
|
||||
*pszDeviceFound = 0;
|
||||
|
||||
for (uiDriver=0; uiDriver<sizeof(drivers_callbacks_list)/sizeof(drivers_callbacks_list[0]); uiDriver++)
|
||||
{
|
||||
if (drivers_callbacks_list[uiDriver].list_devices != NULL)
|
||||
{
|
||||
size_t szN = 0;
|
||||
if (drivers_callbacks_list[uiDriver].list_devices (pnddDevices + (*pszDeviceFound), szDevices - (*pszDeviceFound), &szN))
|
||||
{
|
||||
*pszDeviceFound += szN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nfc_device_t* nfc_connect(nfc_device_desc_t* pndd)
|
||||
{
|
||||
nfc_device_t* pnd;
|
||||
uint32_t uiDev;
|
||||
uint32_t uiDriver;
|
||||
byte_t abtFw[4];
|
||||
size_t szFwLen = sizeof(abtFw);
|
||||
|
||||
// Search through the device list for an available device
|
||||
for (uiDev=0; uiDev<sizeof(drivers_callbacks_list)/sizeof(drivers_callbacks_list[0]); uiDev++)
|
||||
for (uiDriver=0; uiDriver<sizeof(drivers_callbacks_list)/sizeof(drivers_callbacks_list[0]); uiDriver++)
|
||||
{
|
||||
if (pndd == NULL) {
|
||||
// No device description specified: try to automatically claim a device
|
||||
pnd = drivers_callbacks_list[uiDev].connect(pndd);
|
||||
pndd = drivers_callbacks_list[uiDriver].pick_device ();
|
||||
pnd = drivers_callbacks_list[uiDriver].connect(pndd);
|
||||
} else {
|
||||
// Specific device is requested: using device description pndd
|
||||
if( 0 != strcmp(drivers_callbacks_list[uiDev].acDriver, pndd->pcDriver ) )
|
||||
if( 0 != strcmp(drivers_callbacks_list[uiDriver].acDriver, pndd->pcDriver ) )
|
||||
{
|
||||
DBG("Looking for %s, found %s... Skip it.", pndd->pcDriver, drivers_callbacks_list[uiDev].acDriver);
|
||||
DBG("Looking for %s, found %s... Skip it.", pndd->pcDriver, drivers_callbacks_list[uiDriver].acDriver);
|
||||
continue;
|
||||
} else {
|
||||
DBG("Looking for %s, found %s... Use it.", pndd->pcDriver, drivers_callbacks_list[uiDev].acDriver);
|
||||
pnd = drivers_callbacks_list[uiDev].connect(pndd);
|
||||
DBG("Looking for %s, found %s... Use it.", pndd->pcDriver, drivers_callbacks_list[uiDriver].acDriver);
|
||||
pnd = drivers_callbacks_list[uiDriver].connect(pndd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +134,7 @@ nfc_device_t* nfc_connect(nfc_device_desc_t* pndd)
|
|||
{
|
||||
DBG("[%s] has been claimed.", pnd->acName);
|
||||
// Great we have claimed a device
|
||||
pnd->pdc = &(drivers_callbacks_list[uiDev]);
|
||||
pnd->pdc = &(drivers_callbacks_list[uiDriver]);
|
||||
|
||||
// Try to retrieve PN53x chip revision
|
||||
// We can not use pn53x_transceive() because abtRx[0] gives no status info
|
||||
|
@ -125,7 +166,7 @@ nfc_device_t* nfc_connect(nfc_device_desc_t* pndd)
|
|||
|
||||
return pnd;
|
||||
} else {
|
||||
DBG("No device found using driver: %s", drivers_callbacks_list[uiDev].acDriver);
|
||||
DBG("No device found using driver: %s", drivers_callbacks_list[uiDriver].acDriver);
|
||||
}
|
||||
}
|
||||
// To bad, no reader is ready to be claimed
|
||||
|
|
|
@ -36,6 +36,15 @@
|
|||
#define NFCAPI extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
/**
|
||||
* @fn void nfc_list_devices(nfc_device_desc_t *pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
* @brief Probe for discoverable supported devices (ie. only available for some drivers)
|
||||
* @param pnddDevices Array of nfc_device_desc_t previously allocated by the caller.
|
||||
* @param szDevices size of the pnddDevices array.
|
||||
* @param pszDeviceFound number of devices found.
|
||||
*/
|
||||
void nfc_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
|
||||
/**
|
||||
* @fn nfc_device_t* nfc_connect(nfc_device_desc_t* pndd)
|
||||
* @brief Connect to a NFC device
|
||||
|
|
Loading…
Reference in a new issue