From b223ec5780d3e1c2ee1e59e3e5810b626699ce7a Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Mon, 7 Dec 2009 21:13:36 +0000 Subject: [PATCH] add pn531/pn533 _list_devices and _pick routines (plus minor fixes for acr122 and pn532_uart) --- src/examples/nfc-list.c | 22 +++++- src/lib/drivers.h | 4 +- src/lib/drivers/acr122.c | 7 +- src/lib/drivers/pn531_usb.c | 45 ++++++++++-- src/lib/drivers/pn531_usb.h | 2 + src/lib/drivers/pn532_uart.c | 1 + src/lib/drivers/pn533_usb.c | 44 +++++++++-- src/lib/drivers/pn533_usb.h | 2 + src/lib/drivers/pn53x_usb.c | 139 +++++++++++++++++++---------------- src/lib/drivers/pn53x_usb.h | 3 +- 10 files changed, 186 insertions(+), 83 deletions(-) diff --git a/src/examples/nfc-list.c b/src/examples/nfc-list.c index 7f90027..3046ecd 100644 --- a/src/examples/nfc-list.c +++ b/src/examples/nfc-list.c @@ -21,6 +21,13 @@ * @brief */ +#ifdef HAVE_LIBUSB + #ifdef DEBUG + #include + #include + #endif +#endif + #include #include #include @@ -29,6 +36,7 @@ #include + #include #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)) diff --git a/src/lib/drivers.h b/src/lib/drivers.h index d9f9736..6d63165 100644 --- a/src/lib/drivers.h +++ b/src/lib/drivers.h @@ -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 } diff --git a/src/lib/drivers/acr122.c b/src/lib/drivers/acr122.c index 33abdd4..154a24f 100644 --- a/src/lib/drivers/acr122.c +++ b/src/lib/drivers/acr122.c @@ -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 diff --git a/src/lib/drivers/pn531_usb.c b/src/lib/drivers/pn531_usb.c index 16d742b..ce4788d 100644 --- a/src/lib/drivers/pn531_usb.c +++ b/src/lib/drivers/pn531_usb.c @@ -26,17 +26,52 @@ Thanks to d18c7db and Okko for example code */ #include "../drivers.h" +#include -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)); } diff --git a/src/lib/drivers/pn531_usb.h b/src/lib/drivers/pn531_usb.h index fcaccb9..9e0e764 100644 --- a/src/lib/drivers/pn531_usb.h +++ b/src/lib/drivers/pn531_usb.h @@ -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__ diff --git a/src/lib/drivers/pn532_uart.c b/src/lib/drivers/pn532_uart.c index 95d95cf..31f80c6 100644 --- a/src/lib/drivers/pn532_uart.c +++ b/src/lib/drivers/pn532_uart.c @@ -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); diff --git a/src/lib/drivers/pn533_usb.c b/src/lib/drivers/pn533_usb.c index 92d15c6..5a6982c 100644 --- a/src/lib/drivers/pn533_usb.c +++ b/src/lib/drivers/pn533_usb.c @@ -26,17 +26,51 @@ Thanks to d18c7db and Okko for example code */ #include "../drivers.h" +#include -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)); } diff --git a/src/lib/drivers/pn533_usb.h b/src/lib/drivers/pn533_usb.h index 497cccd..ca432a3 100644 --- a/src/lib/drivers/pn533_usb.h +++ b/src/lib/drivers/pn533_usb.h @@ -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__ diff --git a/src/lib/drivers/pn53x_usb.c b/src/lib/drivers/pn53x_usb.c index 3c9180a..99ddc8a 100644 --- a/src/lib/drivers/pn53x_usb.c +++ b/src/lib/drivers/pn53x_usb.c @@ -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; diff --git a/src/lib/drivers/pn53x_usb.h b/src/lib/drivers/pn53x_usb.h index 363ab8a..0f2a8e3 100644 --- a/src/lib/drivers/pn53x_usb.h +++ b/src/lib/drivers/pn53x_usb.h @@ -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);