add pn531/pn533 _list_devices and _pick routines (plus minor fixes for acr122 and pn532_uart)
This commit is contained in:
parent
1909518572
commit
b223ec5780
10 changed files with 186 additions and 83 deletions
|
@ -21,6 +21,13 @@
|
|||
* @brief
|
||||
*/
|
||||
|
||||
#ifdef HAVE_LIBUSB
|
||||
#ifdef DEBUG
|
||||
#include <sys/param.h>
|
||||
#include <usb.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -29,6 +36,7 @@
|
|||
|
||||
#include <nfc/nfc.h>
|
||||
|
||||
|
||||
#include <nfc/nfc-messages.h>
|
||||
#include "bitutils.h"
|
||||
|
||||
|
@ -48,11 +56,17 @@ int main(int argc, const char* argv[])
|
|||
const char* acLibnfcVersion = nfc_version();
|
||||
printf("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||
|
||||
#ifdef HAVE_LIBUSB
|
||||
#ifdef DEBUG
|
||||
usb_set_debug(4);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Lazy way to open an NFC device
|
||||
|
||||
/*
|
||||
pnd = nfc_connect(NULL);
|
||||
*/
|
||||
//pnd = nfc_connect(NULL);
|
||||
//nfc_disconnect(pnd);
|
||||
//return 1;
|
||||
|
||||
// If specific device is wanted, i.e. an ARYGON device on /dev/ttyUSB0
|
||||
/*
|
||||
|
@ -101,7 +115,7 @@ int main(int argc, const char* argv[])
|
|||
// Enable field so more power consuming cards can power themselves up
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,true);
|
||||
|
||||
printf("Connected to NFC reader: %s\n\n",pnd->acName);
|
||||
printf("\nConnected to NFC reader: %s\n\n",pnd->acName);
|
||||
|
||||
// Poll for a ISO14443A (MIFARE) tag
|
||||
if (nfc_initiator_select_tag(pnd,NM_ISO14443A_106,NULL,0,&nti))
|
||||
|
|
|
@ -48,8 +48,8 @@ const static struct driver_callbacks drivers_callbacks_list[] = {
|
|||
{ 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, NULL, pn531_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect },
|
||||
{ PN533_USB_DRIVER_NAME, NULL, NULL, pn533_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect },
|
||||
{ PN531_USB_DRIVER_NAME, pn531_usb_pick_device, pn531_usb_list_devices, pn531_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect },
|
||||
{ PN533_USB_DRIVER_NAME, pn533_usb_pick_device, pn533_usb_list_devices, pn533_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect },
|
||||
#endif /* HAVE_LIBUSB */
|
||||
{ PN532_UART_DRIVER_NAME, pn532_uart_pick_device, pn532_uart_list_devices, pn532_uart_connect, pn532_uart_transceive, pn532_uart_disconnect },
|
||||
{ ARYGON_DRIVER_NAME, NULL, NULL, arygon_connect, arygon_transceive, arygon_disconnect }
|
||||
|
|
|
@ -186,8 +186,11 @@ acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *p
|
|||
}
|
||||
acr122_free_scardcontext ();
|
||||
|
||||
return true;
|
||||
if(*pszDeviceFound)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd)
|
||||
{
|
||||
nfc_device_t* pnd = NULL;
|
||||
|
@ -197,6 +200,8 @@ nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd)
|
|||
|
||||
SCARDCONTEXT *pscc;
|
||||
|
||||
// We no longer support connecting with a NULL
|
||||
if(pndd == NULL) return NULL;
|
||||
// Test if context succeeded
|
||||
if (!(pscc = acr122_get_scardcontext ())) return NULL;
|
||||
// Test if we were able to connect to the "emulator" card
|
||||
|
|
|
@ -26,17 +26,52 @@ Thanks to d18c7db and Okko for example code
|
|||
*/
|
||||
|
||||
#include "../drivers.h"
|
||||
#include <nfc/nfc-messages.h>
|
||||
|
||||
nfc_device_t* pn531_usb_connect(const nfc_device_desc_t* pndd)
|
||||
nfc_device_desc_t * pn531_usb_pick_device (void)
|
||||
{
|
||||
nfc_device_desc_t *pndd;
|
||||
|
||||
if ((pndd = malloc (sizeof (*pndd)))) {
|
||||
size_t szN;
|
||||
|
||||
if (!pn531_usb_list_devices (pndd, 1, &szN)) {
|
||||
DBG("%s", "pn531_usb_list_devices failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (szN == 0) {
|
||||
DBG("%s", "No device found");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pndd;
|
||||
}
|
||||
|
||||
bool pn531_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
{
|
||||
int idvendor = 0x04CC;
|
||||
int idproduct = 0x0531;
|
||||
int idvendor_alt = 0x054c;
|
||||
int idproduct_alt = 0x0193;
|
||||
nfc_device_t* pnd = NULL;
|
||||
|
||||
if((pnd = pn53x_usb_connect(pndd, idvendor, idproduct, "PN531USB", NC_PN531)) == NULL)
|
||||
pnd = pn53x_usb_connect(pndd, idvendor_alt, idproduct_alt, "PN531USB", NC_PN531);
|
||||
size_t firstpass = 0;
|
||||
|
||||
pn53x_usb_list_devices(&pnddDevices[0], szDevices, pszDeviceFound, idvendor, idproduct, PN531_USB_DRIVER_NAME);
|
||||
if(*pszDeviceFound == szDevices)
|
||||
return true;
|
||||
firstpass= *pszDeviceFound;
|
||||
pn53x_usb_list_devices(&pnddDevices[firstpass], szDevices, pszDeviceFound, idvendor_alt, idproduct_alt, PN531_USB_DRIVER_NAME);
|
||||
(*pszDeviceFound) += firstpass;
|
||||
|
||||
return pnd;
|
||||
DBG("Found %d devices",*pszDeviceFound);
|
||||
if(*pszDeviceFound)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
nfc_device_t* pn531_usb_connect(const nfc_device_desc_t* pndd)
|
||||
{
|
||||
return(pn53x_usb_connect(pndd, PN531_USB_DRIVER_NAME, NC_PN531));
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
// Functions used by developer to handle connection to this device
|
||||
nfc_device_t* pn531_usb_connect(const nfc_device_desc_t* pndd);
|
||||
bool pn531_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
nfc_device_desc_t * pn531_usb_pick_device (void);
|
||||
|
||||
#endif // ! __NFC_DRIVER_PN531_USB_H__
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
|||
|
||||
if( pndd == NULL ) {
|
||||
DBG("%s", "pn532_uart_connect() need an nfc_device_desc_t struct.");
|
||||
return NULL;
|
||||
} else {
|
||||
DBG("Connecting to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed);
|
||||
sp = uart_open(pndd->pcPort);
|
||||
|
|
|
@ -26,17 +26,51 @@ Thanks to d18c7db and Okko for example code
|
|||
*/
|
||||
|
||||
#include "../drivers.h"
|
||||
#include <nfc/nfc-messages.h>
|
||||
|
||||
nfc_device_t* pn533_usb_connect(const nfc_device_desc_t* pndd)
|
||||
nfc_device_desc_t * pn533_usb_pick_device (void)
|
||||
{
|
||||
nfc_device_desc_t *pndd;
|
||||
|
||||
if ((pndd = malloc (sizeof (*pndd)))) {
|
||||
size_t szN;
|
||||
|
||||
if (!pn533_usb_list_devices (pndd, 1, &szN)) {
|
||||
DBG("%s", "pn533_usb_list_devices failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (szN == 0) {
|
||||
ERR("%s", "No device found");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pndd;
|
||||
}
|
||||
|
||||
bool pn533_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
{
|
||||
int idvendor = 0x04cc;
|
||||
int idproduct = 0x2533;
|
||||
int idvendor_alt = 0x04e6;
|
||||
int idproduct_alt = 0x5591;
|
||||
nfc_device_t* pnd = NULL;
|
||||
|
||||
if((pnd = pn53x_usb_connect(pndd, idvendor, idproduct, "PN533USB", NC_PN533)) == NULL)
|
||||
pnd = pn53x_usb_connect(pndd, idvendor_alt, idproduct_alt, "PN533USB", NC_PN533);
|
||||
size_t firstpass = 0;
|
||||
|
||||
pn53x_usb_list_devices(&pnddDevices[0], szDevices, pszDeviceFound, idvendor, idproduct, PN533_USB_DRIVER_NAME);
|
||||
if(*pszDeviceFound == szDevices)
|
||||
return true;
|
||||
firstpass= *pszDeviceFound;
|
||||
pn53x_usb_list_devices(&pnddDevices[firstpass], szDevices, pszDeviceFound, idvendor_alt, idproduct_alt, PN533_USB_DRIVER_NAME);
|
||||
(*pszDeviceFound) += firstpass;
|
||||
|
||||
return pnd;
|
||||
if(*pszDeviceFound)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
nfc_device_t* pn533_usb_connect(const nfc_device_desc_t* pndd)
|
||||
{
|
||||
return(pn53x_usb_connect(pndd, PN533_USB_DRIVER_NAME, NC_PN533));
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
// Functions used by developer to handle connection to this device
|
||||
nfc_device_t* pn533_usb_connect(const nfc_device_desc_t* pndd);
|
||||
bool pn533_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
nfc_device_desc_t * pn533_usb_pick_device (void);
|
||||
|
||||
#endif // ! __NFC_DRIVER_PN533_USB_H__
|
||||
|
||||
|
|
|
@ -57,62 +57,40 @@ void get_end_points(struct usb_device *dev, usb_spec_t* pus)
|
|||
// Test if we dealing with a bulk IN endpoint
|
||||
if((uiEndPoint & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Bulk endpoint in : 0x%02X\n", uiEndPoint);
|
||||
#endif
|
||||
DBG("Bulk endpoint in : 0x%02X", uiEndPoint);
|
||||
pus->uiEndPointIn = uiEndPoint;
|
||||
}
|
||||
|
||||
// Test if we dealing with a bulk OUT endpoint
|
||||
if((uiEndPoint & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Bulk endpoint in : 0x%02X\n", uiEndPoint);
|
||||
#endif
|
||||
DBG("Bulk endpoint in : 0x%02X", uiEndPoint);
|
||||
pus->uiEndPointOut = uiEndPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd, int idvendor, int idproduct, char * target_name, int target_chip)
|
||||
bool pn53x_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound,int idvendor, int idproduct, char * target_name)
|
||||
{
|
||||
int ret;
|
||||
static bool usb_inited= false;
|
||||
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
nfc_device_t* pnd = NULL;
|
||||
usb_spec_t* pus;
|
||||
usb_spec_t us;
|
||||
uint32_t uiDevIndex;
|
||||
uint32_t uiBusIndex = 0;
|
||||
|
||||
us.uiEndPointIn = 0;
|
||||
us.uiEndPointOut = 0;
|
||||
us.pudh = NULL;
|
||||
|
||||
DBG("Looking for %s device",target_name);
|
||||
if(!usb_inited)
|
||||
{
|
||||
usb_init();
|
||||
usb_inited= true;
|
||||
}
|
||||
DBG("Looking for %s device (%04x:%04x)",target_name,idvendor,idproduct);
|
||||
usb_init();
|
||||
|
||||
if ((ret= usb_find_busses() < 0)) return NULL;
|
||||
DBG("%d busses",ret);
|
||||
if ((ret= usb_find_devices() < 0)) return NULL;
|
||||
DBG("%d devices",ret);
|
||||
|
||||
|
||||
// Initialize the device index we are seaching for
|
||||
if( pndd == NULL ) {
|
||||
uiDevIndex = 0;
|
||||
} else {
|
||||
uiDevIndex = pndd->uiBusIndex;
|
||||
}
|
||||
*pszDeviceFound= 0;
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next)
|
||||
{
|
||||
for (dev = bus->devices; dev; dev = dev->next)
|
||||
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex++)
|
||||
{
|
||||
DBG("Checking device %04x:%04x",dev->descriptor.idVendor,dev->descriptor.idProduct);
|
||||
if (idvendor==dev->descriptor.idVendor && idproduct==dev->descriptor.idProduct)
|
||||
|
@ -122,23 +100,63 @@ nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd, int idvendor, int
|
|||
if (dev->config == NULL || dev->config->interface == NULL || dev->config->interface->altsetting == NULL)
|
||||
{
|
||||
// Nope, we maybe want the next one, let's try to find another
|
||||
uiDevIndex--;
|
||||
continue;
|
||||
}
|
||||
if (dev->config->interface->altsetting->bNumEndpoints < 2)
|
||||
{
|
||||
// Nope, we maybe want the next one, let's try to find another
|
||||
uiDevIndex--;
|
||||
continue;
|
||||
}
|
||||
// Test if we are looking for this device according to the current index
|
||||
if (uiDevIndex != 0)
|
||||
{
|
||||
// Nope, we maybe want the next one, let's try to find another
|
||||
uiDevIndex--;
|
||||
continue;
|
||||
}
|
||||
DBG("Found %s device", target_name);
|
||||
strcpy(pnddDevices[*pszDeviceFound].acDevice, target_name);
|
||||
pnddDevices[*pszDeviceFound].pcDriver = target_name;
|
||||
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
|
||||
(*pszDeviceFound)++;
|
||||
DBG("%s","Match!");
|
||||
// Test if we reach the maximum "wanted" devices
|
||||
if((*pszDeviceFound) == szDevices) break;
|
||||
}
|
||||
if((*pszDeviceFound) == szDevices) break;
|
||||
}
|
||||
}
|
||||
DBG("Found %d devices",*pszDeviceFound);
|
||||
if(*pszDeviceFound)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd, char * target_name, int target_chip)
|
||||
{
|
||||
int ret;
|
||||
|
||||
nfc_device_t* pnd = NULL;
|
||||
usb_spec_t* pus;
|
||||
usb_spec_t us;
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
|
||||
us.uiEndPointIn = 0;
|
||||
us.uiEndPointOut = 0;
|
||||
us.pudh = NULL;
|
||||
|
||||
uint32_t uiBusIndex;
|
||||
|
||||
// must specify device to connect to
|
||||
if(pndd == NULL) return NULL;
|
||||
|
||||
DBG("Connecting %s device",target_name);
|
||||
usb_init();
|
||||
|
||||
uiBusIndex= pndd->uiBusIndex;
|
||||
|
||||
DBG("Skipping to device no. %d",uiBusIndex);
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next)
|
||||
{
|
||||
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex--)
|
||||
{
|
||||
DBG("Checking device %04x:%04x",dev->descriptor.idVendor,dev->descriptor.idProduct);
|
||||
if(uiBusIndex == 0)
|
||||
{
|
||||
DBG("Found device index %d", pndd->uiBusIndex);
|
||||
|
||||
// Open the USB device
|
||||
us.pudh = usb_open(dev);
|
||||
|
@ -148,26 +166,16 @@ nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd, int idvendor, int
|
|||
{
|
||||
DBG("%s", "Setting config failed");
|
||||
usb_close(us.pudh);
|
||||
if (pndd == NULL) {
|
||||
// don't return yet as there might be other readers on USB bus
|
||||
continue;
|
||||
} else {
|
||||
// we failed to use the specified device
|
||||
return NULL;
|
||||
}
|
||||
// we failed to use the specified device
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(usb_claim_interface(us.pudh,0) < 0)
|
||||
{
|
||||
DBG("%s", "Can't claim interface");
|
||||
usb_close(us.pudh);
|
||||
if (pndd == NULL) {
|
||||
// don't return yet as there might be other readers on USB bus
|
||||
continue;
|
||||
} else {
|
||||
// we failed to use the specified device
|
||||
return NULL;
|
||||
}
|
||||
// we failed to use the specified device
|
||||
return NULL;
|
||||
}
|
||||
// Allocate memory for the device info and specification, fill it and return the info
|
||||
pus = malloc(sizeof(usb_spec_t));
|
||||
|
@ -184,7 +192,8 @@ nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd, int idvendor, int
|
|||
}
|
||||
}
|
||||
}
|
||||
return pnd;
|
||||
// We ran out of devices before the index required
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void pn53x_usb_disconnect(nfc_device_t* pnd)
|
||||
|
@ -200,6 +209,7 @@ void pn53x_usb_disconnect(nfc_device_t* pnd)
|
|||
DBG("usb_close failed %i",ret);
|
||||
free(pnd->nds);
|
||||
free(pnd);
|
||||
DBG("%s","done!");
|
||||
}
|
||||
|
||||
bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
||||
|
@ -227,6 +237,7 @@ bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, cons
|
|||
// End of stream marker
|
||||
abtTx[szTxLen+6] = 0;
|
||||
|
||||
DBG("%s","pn53x_usb_transceive");
|
||||
#ifdef DEBUG
|
||||
printf(" TX: ");
|
||||
print_hex(abtTx,szTxLen+7);
|
||||
|
@ -235,18 +246,14 @@ bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, cons
|
|||
ret = usb_bulk_write(pus->pudh, pus->uiEndPointOut, (char*)abtTx, szTxLen+7, USB_TIMEOUT);
|
||||
if( ret < 0 )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("usb_bulk_write failed with error %d\n", ret);
|
||||
#endif
|
||||
DBG("usb_bulk_write failed with error %d", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = usb_bulk_read(pus->pudh, pus->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
if( ret < 0 )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf( "usb_bulk_read failed with error %d\n", ret);
|
||||
#endif
|
||||
DBG( "usb_bulk_read failed with error %d", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -260,9 +267,7 @@ bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, cons
|
|||
ret = usb_bulk_read(pus->pudh, pus->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
if( ret < 0 )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("usb_bulk_read failed with error %d\n", ret);
|
||||
#endif
|
||||
DBG("usb_bulk_read failed with error %d", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -276,7 +281,11 @@ bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, cons
|
|||
if(pbtRx == NULL || pszRxLen == NULL) return true;
|
||||
|
||||
// Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
|
||||
if(ret < 9) return false;
|
||||
if(ret < 9)
|
||||
{
|
||||
DBG("%s","No data");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the preceding and appending bytes 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
|
||||
*pszRxLen = ret - 7 - 2;
|
||||
|
|
|
@ -33,7 +33,8 @@ typedef struct {
|
|||
uint32_t uiEndPointOut;
|
||||
} usb_spec_t;
|
||||
|
||||
nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd, int idvendor, int idproduct, char * target_name, int target_chip);
|
||||
nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd, char * target_name, int target_chip);
|
||||
void get_end_points(struct usb_device *dev, usb_spec_t* pus);
|
||||
void pn53x_usb_disconnect(nfc_device_t* pnd);
|
||||
bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool pn53x_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound,int idvendor, int idproduct, char * target_name);
|
||||
|
|
Loading…
Reference in a new issue