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:
Romain Tartiere
2009-11-24 17:49:24 +00:00
parent 1af29561e8
commit 220bef3490
20 changed files with 248 additions and 94 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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