diff --git a/configure.ac b/configure.ac index ba670d9..5e5a2c7 100644 --- a/configure.ac +++ b/configure.ac @@ -33,18 +33,6 @@ AC_TYPE_UINT32_T AC_TYPE_UINT64_T AC_TYPE_INT32_T -# --enable-pcsc-lite support (default: yes) -AC_ARG_ENABLE([pcsc-lite],AS_HELP_STRING([--enable-pcsc-lite],[pcsc-lite feature flag]),[enable_pcsc_lite=$enableval],[enable_pcsc_lite="yes"]) - -AC_MSG_CHECKING(for pcsc-lite support) -AC_MSG_RESULT($enable_pcsc_lite) - -if test x"$enable_pcsc_lite" = "xno" -then - WITH_PCSC=0 -fi -AM_CONDITIONAL(PCSC_LITE_ENABLED, [test x"$enable_pcsc_lite" = xyes]) - # --enable-debug support (default:no) AC_ARG_ENABLE([debug],AS_HELP_STRING([--enable-debug],[Debug flags]),[enable_debug=$enableval],[enable_debug="no"]) @@ -57,6 +45,29 @@ then fi AC_SUBST([DEBUG_CFLAGS]) +# --enable-serial-autoprobe support (default:yes) +AC_ARG_ENABLE([serial-autoprobe],AS_HELP_STRING([--enable-serial-autoprobe],[Serial autoprobing flag]),[enable_serial_autoprobe=$enableval],[enable_serial_autoprobe="yes"]) + +AC_MSG_CHECKING(for serial autoprobe flag) +AC_MSG_RESULT($enable_serial_autoprobe) + +if test x"$enable_serial_autoprobe" = "xno" +then + CFLAGS="$CFLAGS -DDISABLE_SERIAL_AUTOPROBE" +fi + +# --enable-pcsc-lite support (default: yes) +AC_ARG_ENABLE([pcsc-lite],AS_HELP_STRING([--enable-pcsc-lite],[pcsc-lite feature flag]),[enable_pcsc_lite=$enableval],[enable_pcsc_lite="yes"]) + +AC_MSG_CHECKING(for pcsc-lite support) +AC_MSG_RESULT($enable_pcsc_lite) + +if test x"$enable_pcsc_lite" = "xno" +then + WITH_PCSC=0 +fi +AM_CONDITIONAL(PCSC_LITE_ENABLED, [test x"$enable_pcsc_lite" = xyes]) + ## libusb if test x"$PKG_CONFIG" = "x"; then AC_PATH_PROG(LIBUSB_CONFIG,libusb-config) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d89bb5c..ea17dc5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,10 @@ IF(LIBNFC_VERBOSE_OUTPUT) ADD_DEFINITIONS("-DDEBUG") ENDIF(LIBNFC_VERBOSE_OUTPUT) +IF(LIBNFC_DISABLE_SERIAL_AUTOPROBE) + ADD_DEFINITIONS("-DDISABLE_SERIAL_AUTOPROBE") +ENDIF(LIBNFC_DISABLE_SERIAL_AUTOPROBE) + IF(LIBNFC_LANG_C99 AND NOT MSVC) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") ENDIF(LIBNFC_LANG_C99 AND NOT MSVC) diff --git a/src/anticol.c b/src/anticol.c index 4011c8d..d8bb445 100644 --- a/src/anticol.c +++ b/src/anticol.c @@ -117,7 +117,7 @@ int main(int argc,char* argv[]) } // Try to open the NFC reader - pdi = nfc_connect(); + pdi = nfc_connect(NULL); if (!pdi) { diff --git a/src/dev_acr122.c b/src/dev_acr122.c index 5107645..4d67766 100644 --- a/src/dev_acr122.c +++ b/src/dev_acr122.c @@ -62,7 +62,7 @@ static size_t ulRxBufLen; static byte_t abtGetFw[5] = { 0xFF,0x00,0x48,0x00,0x00 }; static byte_t abtLed[9] = { 0xFF,0x00,0x40,0x05,0x04,0x00,0x00,0x00,0x00 }; -dev_info* dev_acr122_connect(const uint32_t uiIndex) +dev_info* dev_acr122_connect(const nfc_device_desc_t* device_desc) { char* pacReaders[MAX_DEVICES]; char acList[256+64*MAX_DEVICES]; @@ -117,8 +117,12 @@ dev_info* dev_acr122_connect(const uint32_t uiIndex) } // Initialize the device index we are seaching for - uiDevIndex = uiIndex; - + if( device_desc == NULL ) { + uiDevIndex = 0; + } else { + uiDevIndex = device_desc->index; + } + // Iterate through all readers and try to find the ACR122 on requested index for (uiReader=0; uiReader #include "types.h" // Functions used by developer to handle connection to this device -dev_info* dev_acr122_connect(const uint32_t uiIndex); +dev_info* dev_acr122_connect(const nfc_device_desc_t* device_desc); void dev_acr122_disconnect(dev_info* pdi); // Callback function used by libnfc to transmit commands to the PN53X chip diff --git a/src/dev_arygon.c b/src/dev_arygon.c index f01ba91..1db1140 100644 --- a/src/dev_arygon.c +++ b/src/dev_arygon.c @@ -28,8 +28,8 @@ along with this program. If not, see #ifdef __APPLE__ #define SERIAL_STRING "/dev/tty.SLAB_USBtoUART" #else - // unistd.h is needed for udelay() fct. - #include "unistd.h" + // unistd.h is needed for usleep() fct. + #include #define SERIAL_STRING "/dev/ttyUSB" #endif #endif @@ -56,33 +56,45 @@ along with this program. If not, see static byte_t abtTxBuf[BUFFER_LENGTH] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff" -dev_info* dev_arygon_connect(const uint32_t uiIndex) +dev_info* dev_arygon_connect(const nfc_device_desc_t* device_desc) { uint32_t uiDevNr; serial_port sp; char acConnect[BUFFER_LENGTH]; dev_info* pdi = INVALID_DEVICE_INFO; - DBG("Trying to find ARYGON device on serial port: %s#",SERIAL_STRING); - - // I have no idea how MAC OS X deals with multiple devices, so a quick workaround - for (uiDevNr=0; uiDevNrport); + sp = rs232_open(acConnect); + if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",acConnect); + if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",acConnect); + if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return INVALID_DEVICE_INFO; } - // Test if we have found a device - if (uiDevNr == MAX_DEVICES) return INVALID_DEVICE_INFO; DBG("Successfully connected to: %s",acConnect); diff --git a/src/dev_arygon.h b/src/dev_arygon.h index 885b7dc..d895584 100644 --- a/src/dev_arygon.h +++ b/src/dev_arygon.h @@ -25,7 +25,7 @@ along with this program. If not, see #include "types.h" // Functions used by developer to handle connection to this device -dev_info* dev_arygon_connect(const uint32_t uiIndex); +dev_info* dev_arygon_connect(const nfc_device_desc_t* device_desc); void dev_arygon_disconnect(dev_info* pdi); // Callback function used by libnfc to transmit commands to the PN53X chip diff --git a/src/dev_pn531.c b/src/dev_pn531.c index 82e7620..84cbe54 100644 --- a/src/dev_pn531.c +++ b/src/dev_pn531.c @@ -51,7 +51,7 @@ static void get_end_points(struct usb_device *dev, dev_spec_pn531* pdsp) // 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out for(uiIndex = 0; uiIndex < puid->bNumEndpoints; uiIndex++) - { + { // Only accept bulk transfer endpoints (ignore interrupt endpoints) if(puid->endpoint[uiIndex].bmAttributes != USB_ENDPOINT_TYPE_BULK) continue; @@ -76,10 +76,10 @@ static void get_end_points(struct usb_device *dev, dev_spec_pn531* pdsp) pdsp->uiEndPointOut = uiEndPoint; } } -} +} -dev_info* dev_pn531_connect(const uint32_t uiIndex) -{ +dev_info* dev_pn531_connect(const nfc_device_desc_t* device_desc) +{ int idvendor = 0x04CC; int idproduct = 0x0531; int idvendor_alt = 0x054c; @@ -94,24 +94,28 @@ dev_info* dev_pn531_connect(const uint32_t uiIndex) dsp.uiEndPointIn = 0; dsp.uiEndPointOut = 0; dsp.pudh = NULL; - + usb_init(); if (usb_find_busses() < 0) return INVALID_DEVICE_INFO; if (usb_find_devices() < 0) return INVALID_DEVICE_INFO; // Initialize the device index we are seaching for - uiDevIndex = uiIndex; + if( device_desc == NULL ) { + uiDevIndex = 0; + } else { + uiDevIndex = device_desc->index; + } for (bus = usb_get_busses(); bus; bus = bus->next) - { + { for (dev = bus->devices; dev; dev = dev->next) - { + { if ((idvendor==dev->descriptor.idVendor && idproduct==dev->descriptor.idProduct) || (idvendor_alt==dev->descriptor.idVendor && idproduct_alt==dev->descriptor.idProduct)) - { + { // Make sure there are 2 endpoints available if (dev->config->interface->altsetting->bNumEndpoints < 2) return pdi; - + // Test if we are looking for this device according to the current index if (uiDevIndex != 0) { @@ -126,13 +130,13 @@ dev_info* dev_pn531_connect(const uint32_t uiIndex) // Open the PN531 USB device dsp.pudh = usb_open(dev); - get_end_points(dev,&dsp); - if(usb_set_configuration(dsp.pudh,1) < 0) - { + get_end_points(dev,&dsp); + if(usb_set_configuration(dsp.pudh,1) < 0) + { #ifdef DEBUG - printf("Setting config failed\n"); + printf("Setting config failed\n"); #endif - usb_close(dsp.pudh); + usb_close(dsp.pudh); return INVALID_DEVICE_INFO; } @@ -160,21 +164,21 @@ dev_info* dev_pn531_connect(const uint32_t uiIndex) } } return pdi; -} +} void dev_pn531_disconnect(dev_info* pdi) { dev_spec_pn531* pdsp = (dev_spec_pn531*)pdi->ds; usb_release_interface(pdsp->pudh,0); - usb_close(pdsp->pudh); + usb_close(pdsp->pudh); free(pdi->ds); free(pdi); -} +} bool dev_pn531_transceive(const dev_spec ds, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen) -{ - uint32_t uiPos = 0; - int ret = 0; +{ + uint32_t uiPos = 0; + int ret = 0; char buf[BUFFER_LENGTH]; dev_spec_pn531* pdsp = (dev_spec_pn531*)ds; diff --git a/src/dev_pn531.h b/src/dev_pn531.h index 51279e8..bc42930 100644 --- a/src/dev_pn531.h +++ b/src/dev_pn531.h @@ -28,7 +28,7 @@ along with this program. If not, see #include "types.h" // Functions used by developer to handle connection to this device -dev_info* dev_pn531_connect(const uint32_t uiIndex); +dev_info* dev_pn531_connect(const nfc_device_desc_t* device_desc); void dev_pn531_disconnect(dev_info* pdi); // Callback function used by libnfc to transmit commands to the PN53X chip diff --git a/src/dev_pn533.c b/src/dev_pn533.c index d73897a..6405bad 100644 --- a/src/dev_pn533.c +++ b/src/dev_pn533.c @@ -49,7 +49,7 @@ static void get_end_points(struct usb_device *dev, dev_spec_pn533* pdsp) // 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out for(uiIndex = 0; uiIndex < puid->bNumEndpoints; uiIndex++) - { + { // Only accept bulk transfer endpoints (ignore interrupt endpoints) if(puid->endpoint[uiIndex].bmAttributes != USB_ENDPOINT_TYPE_BULK) continue; @@ -74,10 +74,10 @@ static void get_end_points(struct usb_device *dev, dev_spec_pn533* pdsp) pdsp->uiEndPointOut = uiEndPoint; } } -} +} -dev_info* dev_pn533_connect(const uint32_t uiIndex) -{ +dev_info* dev_pn533_connect(const nfc_device_desc_t* device_desc) +{ int idvendor = 0x04e6; int idproduct = 0x5591; struct usb_bus *bus; @@ -90,23 +90,27 @@ dev_info* dev_pn533_connect(const uint32_t uiIndex) dsp.uiEndPointIn = 0; dsp.uiEndPointOut = 0; dsp.pudh = NULL; - + usb_init(); if (usb_find_busses() < 0) return INVALID_DEVICE_INFO; if (usb_find_devices() < 0) return INVALID_DEVICE_INFO; // Initialize the device index we are seaching for - uiDevIndex = uiIndex; + if( device_desc == NULL ) { + uiDevIndex = 0; + } else { + uiDevIndex = device_desc->index; + } for (bus = usb_get_busses(); bus; bus = bus->next) - { + { for (dev = bus->devices; dev; dev = dev->next) - { + { if (idvendor==dev->descriptor.idVendor && idproduct==dev->descriptor.idProduct) - { + { // Make sure there are 2 endpoints available if (dev->config->interface->altsetting->bNumEndpoints < 2) return pdi; - + // Test if we are looking for this device according to the current index if (uiDevIndex != 0) { diff --git a/src/dev_pn533.h b/src/dev_pn533.h index 8bf0587..8236248 100644 --- a/src/dev_pn533.h +++ b/src/dev_pn533.h @@ -25,7 +25,7 @@ along with this program. If not, see #include "types.h" // Functions used by developer to handle connection to this device -dev_info* dev_pn533_connect(const uint32_t uiIndex); +dev_info* dev_pn533_connect(const nfc_device_desc_t* device_desc); void dev_pn533_disconnect(dev_info* pdi); // Callback function used by libnfc to transmit commands to the PN53X chip diff --git a/src/emulate.c b/src/emulate.c index 7c89057..900ee66 100644 --- a/src/emulate.c +++ b/src/emulate.c @@ -80,7 +80,7 @@ int main(int argc, char *argv[]) } // Try to open the NFC reader - pdi = nfc_connect(); + pdi = nfc_connect(NULL); if (pdi == INVALID_DEVICE_INFO) { diff --git a/src/initiator.c b/src/initiator.c index c3e4d95..8b27657 100644 --- a/src/initiator.c +++ b/src/initiator.c @@ -10,7 +10,7 @@ int main(int argc, const char *argv[]) uint32_t uiRecvBits; byte_t send[] = "Hello World!"; - pdi = nfc_connect(); + pdi = nfc_connect(NULL); if (!pdi || !nfc_initiator_init(pdi) || !nfc_initiator_select_dep_target(pdi, IM_PASSIVE_DEP, NULL, 0, NULL, 0, NULL, 0, &ti)) { diff --git a/src/libnfc.c b/src/libnfc.c index 5fd0eca..36ccb89 100644 --- a/src/libnfc.c +++ b/src/libnfc.c @@ -253,7 +253,7 @@ bool pn53x_unwrap_frame(const byte_t* pbtFrame, const uint32_t uiFrameBits, byte } } -dev_info* nfc_connect() +dev_info* nfc_connect(nfc_device_desc_t* device_desc) { dev_info* pdi; uint32_t uiDev; @@ -263,8 +263,20 @@ dev_info* nfc_connect() // Search through the device list for an available device for (uiDev=0; uiDevdriver ) ) + { + DBG("Looking for %s, found %s... Skip it.", device_desc->driver, dev_callbacks_list[uiDev].acDriver); + continue; + } else { + DBG("Looking for %s, found %s... Use it.", device_desc->driver, dev_callbacks_list[uiDev].acDriver); + pdi = dev_callbacks_list[uiDev].connect(device_desc); + } + } // Test if the connection was successful if (pdi != INVALID_DEVICE_INFO) diff --git a/src/libnfc.h b/src/libnfc.h index 82aa7de..00ffee5 100644 --- a/src/libnfc.h +++ b/src/libnfc.h @@ -35,16 +35,20 @@ along with this program. If not, see #include "bitutils.h" /** - * @fn dev_info* nfc_connect() + * @fn dev_info* nfc_connect(nfc_device_desc_t* device_desc) * @brief Connect to a NFC device + * @param device_desc Device description if specific device is wanted, NULL otherwise * @return Returns pointer to a dev_info struct if successfull; otherwise returns INVALID_DEVICE_INFO value. * - * The first available NFC device is claimed by libnfc. + * If device_desc is NULL, the first available NFC device is claimed by libnfc. * It will automatically search the system using all available drivers to determine a device is free. + * + * If device_desc is passed then libnfc will try to claim the right device using information provided by this struct. + * * When it has successfully claimed a NFC device, memory is allocated to save the device information. It will return a pointer to a dev_info struct. * This pointer should be supplied by every next function of libnfc that should perform an action with this device. */ -LIBNFC_EXPORT dev_info* nfc_connect(void); +LIBNFC_EXPORT dev_info* nfc_connect(nfc_device_desc_t* device_desc); /** * @fn void nfc_disconnect(dev_info* pdi) diff --git a/src/list.c b/src/list.c index ec94bc2..31f725e 100644 --- a/src/list.c +++ b/src/list.c @@ -33,8 +33,17 @@ int main(int argc, const char* argv[]) { tag_info ti; - // Try to open the NFC reader - pdi = nfc_connect(); + // Try to open the NFC device + pdi = nfc_connect(NULL); + + // If specific device is wanted, i.e. an ARYGON device on /dev/ttyUSB0 + /* + nfc_device_desc_t device_desc; + device_desc.driver = "ARYGON"; + device_desc.port = "/dev/ttyUSB0"; + + pdi = nfc_connect(&device_desc); + */ if (pdi == INVALID_DEVICE_INFO) { diff --git a/src/mftool.c b/src/mftool.c index 7f41926..ff81e81 100644 --- a/src/mftool.c +++ b/src/mftool.c @@ -290,7 +290,7 @@ int main(int argc, const char* argv[]) printf("Succesful opened MIFARE the required files\n"); // Try to open the NFC reader - pdi = nfc_connect(); + pdi = nfc_connect(NULL); if (pdi == INVALID_DEVICE_INFO) { printf("Error connecting NFC reader\n"); diff --git a/src/mfultool.c b/src/mfultool.c index c394482..3e1f0da 100644 --- a/src/mfultool.c +++ b/src/mfultool.c @@ -144,7 +144,7 @@ int main(int argc, const char* argv[]) printf("Succesful opened the dump file\n"); // Try to open the NFC reader - pdi = nfc_connect(); + pdi = nfc_connect(NULL); if (pdi == INVALID_DEVICE_INFO) { printf("Error connecting NFC reader\n"); diff --git a/src/relay.c b/src/relay.c index 6c73a1c..c32e3d8 100644 --- a/src/relay.c +++ b/src/relay.c @@ -60,7 +60,7 @@ int main(int argc,char* argv[]) // Try to open the NFC emulator device - pdiTag = nfc_connect(); + pdiTag = nfc_connect(NULL); if (pdiTag == INVALID_DEVICE_INFO) { printf("Error connecting NFC emulator device\n"); @@ -81,7 +81,7 @@ int main(int argc,char* argv[]) // Try to open the NFC reader pdiReader = INVALID_DEVICE_INFO; - while (pdiReader == INVALID_DEVICE_INFO) pdiReader = nfc_connect(); + while (pdiReader == INVALID_DEVICE_INFO) pdiReader = nfc_connect(NULL); printf("[+] Configuring NFC reader settings\n"); nfc_configure(pdiReader,DCO_HANDLE_CRC,false); nfc_configure(pdiReader,DCO_HANDLE_PARITY,false); diff --git a/src/target.c b/src/target.c index fe65aa2..651b5bf 100644 --- a/src/target.c +++ b/src/target.c @@ -6,7 +6,7 @@ int main(int argc, const char *argv[]) byte_t abtRecv[MAX_FRAME_LEN]; uint32_t uiRecvBits; byte_t send[] = "Hello Mars!"; - dev_info *pdi = nfc_connect(); + dev_info *pdi = nfc_connect(NULL); if (!pdi || !nfc_target_init(pdi, abtRecv, &uiRecvBits)) { printf("unable to connect or initialize\n"); diff --git a/src/types.h b/src/types.h index fcb5809..45b61d1 100644 --- a/src/types.h +++ b/src/types.h @@ -69,6 +69,21 @@ typedef struct { uint8_t ui8TxBits; } dev_info; +/** + * @struct nfc_device_desc_t + * @brief NFC device description + * + * This struct is used to try to connect to a specified nfc device when nfc_connect(...) + */ +typedef struct { + /** Driver name */ + char* driver; + /** Port (i.e. /dev/ttyUSB2) */ + char* port; + /** Device index for backward compatibility (used to choose one specific device in USB or PSCS devices list) */ + uint32_t index; +} nfc_device_desc_t; + /** * @struct dev_callbacks * @brief NFC defice callbacks @@ -77,7 +92,7 @@ struct dev_callbacks { /** Driver name */ const char* acDriver; /** Connect callback */ - dev_info* (*connect)(const uint32_t uiIndex); + dev_info* (*connect)(const nfc_device_desc_t* device_desc); /** Transceive callback */ bool (*transceive)(const dev_spec ds, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen); /** Disconnect callback */