diff --git a/Makefile.am b/Makefile.am index 4ba301d..4a730c4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/README b/README index f1e4d59..c2117e1 100644 --- a/README +++ b/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. diff --git a/debian/changelog b/debian/changelog index c4c28e8..5de1338 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +libnfc (1.2.1-4) unstable; urgency=low + + * Add udev rules for USB PN53x. + + -- Romuald Conty 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. diff --git a/debian/libnfc0.install b/debian/libnfc0.install index 5ae0ff4..809e47b 100644 --- a/debian/libnfc0.install +++ b/debian/libnfc0.install @@ -1 +1,2 @@ debian/tmp/usr/lib/libnfc.so.* +pn53x.rules etc/udev/rules.d/ diff --git a/pn53x.rules b/pn53x.rules new file mode 100644 index 0000000..b7219cb --- /dev/null +++ b/pn53x.rules @@ -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" diff --git a/src/examples/nfc-list.c b/src/examples/nfc-list.c index 967a5fa..b6466d9 100644 --- a/src/examples/nfc-list.c +++ b/src/examples/nfc-list.c @@ -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; } diff --git a/src/examples/nfc-relay.c b/src/examples/nfc-relay.c index bb1d110..04b520b 100644 --- a/src/examples/nfc-relay.c +++ b/src/examples/nfc-relay.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -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)) diff --git a/src/lib/bitutils.c b/src/lib/bitutils.c index be9a5a1..71dc29a 100644 --- a/src/lib/bitutils.c +++ b/src/lib/bitutils.c @@ -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"); } diff --git a/src/lib/buses/uart.c b/src/lib/buses/uart.c index 6e817f1..c12aa3d 100644 --- a/src/lib/buses/uart.c +++ b/src/lib/buses/uart.c @@ -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; } diff --git a/src/lib/chips/pn53x.c b/src/lib/chips/pn53x.c index e0b9bd3..ac405e9 100644 --- a/src/lib/chips/pn53x.c +++ b/src/lib/chips/pn53x.c @@ -21,6 +21,7 @@ * @brief PN531, PN532 and PN533 common functions */ +#include #include #include "pn53x.h" diff --git a/src/lib/drivers.h b/src/lib/drivers.h index 716a8a9..d20a981 100644 --- a/src/lib/drivers.h +++ b/src/lib/drivers.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__ diff --git a/src/lib/drivers/acr122.c b/src/lib/drivers/acr122.c index 841665b..17a5352 100644 --- a/src/lib/drivers/acr122.c +++ b/src/lib/drivers/acr122.c @@ -28,7 +28,7 @@ #include "acr122.h" #include "../drivers.h" - +#include "../bitutils.h" // Bus #include @@ -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); } diff --git a/src/lib/drivers/acr122.h b/src/lib/drivers/acr122.h index b2278f6..8291cc5 100644 --- a/src/lib/drivers/acr122.h +++ b/src/lib/drivers/acr122.h @@ -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); diff --git a/src/lib/drivers/arygon.c b/src/lib/drivers/arygon.c index 094af68..b63c2b9 100644 --- a/src/lib/drivers/arygon.c +++ b/src/lib/drivers/arygon.c @@ -20,7 +20,7 @@ * @file arygon.c * @brief */ - +#define _XOPEN_SOURCE 500 #include #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; } diff --git a/src/lib/drivers/pn531_usb.c b/src/lib/drivers/pn531_usb.c index b3c3392..2e278d9 100644 --- a/src/lib/drivers/pn531_usb.c +++ b/src/lib/drivers/pn531_usb.c @@ -28,14 +28,13 @@ Thanks to d18c7db and Okko for example code #include #include #include + +#include #include #include "pn531_usb.h" #include "../drivers.h" -// Bus -#include - #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)); diff --git a/src/lib/drivers/pn532_uart.c b/src/lib/drivers/pn532_uart.c index 10843b0..d4d06c5 100644 --- a/src/lib/drivers/pn532_uart.c +++ b/src/lib/drivers/pn532_uart.c @@ -20,7 +20,7 @@ * @file pn532_uart.c * @brief */ - +#define _XOPEN_SOURCE 500 #include #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; } diff --git a/src/lib/drivers/pn533_usb.c b/src/lib/drivers/pn533_usb.c index d4041d5..d9ec310 100644 --- a/src/lib/drivers/pn533_usb.c +++ b/src/lib/drivers/pn533_usb.c @@ -27,14 +27,12 @@ Thanks to d18c7db and Okko for example code #include #include +#include #include #include "pn533_usb.h" #include "../drivers.h" -// Bus -#include - #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)); diff --git a/src/lib/nfc-types.h b/src/lib/nfc-types.h index 83f4d76..8f3c7a7 100644 --- a/src/lib/nfc-types.h +++ b/src/lib/nfc-types.h @@ -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 */ diff --git a/src/lib/nfc.c b/src/lib/nfc.c index d9dcc0b..442f34d 100644 --- a/src/lib/nfc.c +++ b/src/lib/nfc.c @@ -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; uiDriverpcDriver ) ) + 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 diff --git a/src/lib/nfc.h b/src/lib/nfc.h index 662ea25..f94bc6f 100644 --- a/src/lib/nfc.h +++ b/src/lib/nfc.h @@ -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