WARNING: API changed: nfc_connect() now take one argument. Have a look at nfc-list example (list.c) or at directly at function Doxygen comment (libnfc.h).

Add configure option: --disable-serial-autoprobe to fix Issue 2 (Autotools and CMake).
Fix Issue 11: it is now possible to specify a wanted device using new struct "nfc_device_desc_t".
Code cleanup.
This commit is contained in:
Romuald Conty 2009-09-04 13:24:34 +00:00
parent ecb406b4ea
commit be55ba2955
21 changed files with 163 additions and 84 deletions

View file

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

View file

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

View file

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

View file

@ -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<uiReaderCount; uiReader++)
{
@ -134,7 +138,7 @@ dev_info* dev_acr122_connect(const uint32_t uiIndex)
}
// Configure I/O settings for card communication
dsa.ioCard.cbPciLength = sizeof(SCARD_IO_REQUEST);
// Retrieve the current firmware version
pcFirmware = dev_acr122_firmware((dev_info*)&dsa);
if (strstr(pcFirmware,FIRMWARE_TEXT) != NULL)

View file

@ -28,7 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#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

View file

@ -28,8 +28,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#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 <unistd.h>
#define SERIAL_STRING "/dev/ttyUSB"
#endif
#endif
@ -56,33 +56,45 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
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; uiDevNr<MAX_DEVICES; uiDevNr++)
{
#ifdef __APPLE__
if( device_desc == NULL ) {
#ifdef DISABLE_SERIAL_AUTOPROBE
INFO("Sorry, serial auto-probing have been disabled at compile time.");
return INVALID_DEVICE_INFO;
#else
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; uiDevNr<MAX_DEVICES; uiDevNr++)
{
#ifdef __APPLE__
strcpy(acConnect,SERIAL_STRING);
sp = rs232_open(acConnect);
#else
#else
sprintf(acConnect,"%s%d",SERIAL_STRING,uiDevNr);
sp = rs232_open(acConnect);
#endif
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) break;
#ifdef DEBUG
#endif /* __APPLE__ */
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) break;
#ifdef DEBUG
if (sp == INVALID_SERIAL_PORT) DBG("Invalid serial port: %s",acConnect);
if (sp == CLAIMED_SERIAL_PORT) DBG("Serial port already claimed: %s",acConnect);
#endif
#endif /* DEBUG */
}
#endif
// Test if we have found a device
if (uiDevNr == MAX_DEVICES) return INVALID_DEVICE_INFO;
} else {
strcpy(acConnect,device_desc->port);
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);

View file

@ -25,7 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#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

View file

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

View file

@ -28,7 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#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

View file

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

View file

@ -25,7 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#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

View file

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

View file

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

View file

@ -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; uiDev<sizeof(dev_callbacks_list)/sizeof(dev_callbacks_list[0]); uiDev++)
{
// Try to claim the device
pdi = dev_callbacks_list[uiDev].connect(0);
if (device_desc == NULL) {
// No device description specified: try to automatically claim a device
pdi = dev_callbacks_list[uiDev].connect(device_desc);
} else {
// Specific device is requested: using device description device_desc
if( 0 != strcmp(dev_callbacks_list[uiDev].acDriver, device_desc->driver ) )
{
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)

View file

@ -35,16 +35,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#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)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 */