From d77c25224ad83e537c9f5146d83fbf9dc43d435c Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Sat, 31 Jul 2010 15:37:27 +0000 Subject: [PATCH 1/6] After a bazillion tests, make the Debian-5-year-outdated-and-buggy autotools happy with some weird m4 syntax and hope it will not fail on a much more recent autolol suite. --- m4/libnfc_drivers.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/m4/libnfc_drivers.m4 b/m4/libnfc_drivers.m4 index d51883f..0c7296f 100644 --- a/m4/libnfc_drivers.m4 +++ b/m4/libnfc_drivers.m4 @@ -4,7 +4,7 @@ AC_DEFUN([LIBNFC_ARG_WITH_DRIVERS], [ AC_MSG_CHECKING(which drivers to build) AC_ARG_WITH(drivers, - AC_HELP_STRING([[[--with-drivers=driver@<:@,driver...@:>@]]], [Only use specific drivers (default set)]), + AC_HELP_STRING([--with-drivers=driver@<:@[[[,]]]driver...@:>@], [Only use specific drivers (default set)]), [ case "${withval}" in yes | no) dnl ignore calls without any arguments From 8e5d235cd2d802a44dc50d2da483f49c9be7324e Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Fri, 6 Aug 2010 07:29:57 +0000 Subject: [PATCH 2/6] Implement pn53x_InRelease(). I used it for some experiments and guess that it should be part of the API. --- libnfc/chips/pn53x.c | 10 ++++++++++ libnfc/chips/pn53x.h | 1 + 2 files changed, 11 insertions(+) diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index 2ee216b..2431ea7 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -325,3 +325,13 @@ pn53x_InDeselect(const nfc_device_t* pnd, const uint8_t ui8Target) return(pn53x_transceive(pnd,abtCmd,sizeof(abtCmd),NULL,NULL)); } + +bool +pn53x_InRelease(nfc_device_t* pnd, const uint8_t ui8Target) +{ + byte_t abtCmd[sizeof(pncmd_initiator_release)]; + memcpy(abtCmd,pncmd_initiator_release,sizeof(pncmd_initiator_release)); + abtCmd[2] = ui8Target; + + return(pn53x_transceive(pnd,abtCmd,sizeof(abtCmd),NULL,NULL)); +} diff --git a/libnfc/chips/pn53x.h b/libnfc/chips/pn53x.h index cc6ce59..fbcc784 100644 --- a/libnfc/chips/pn53x.h +++ b/libnfc/chips/pn53x.h @@ -80,6 +80,7 @@ bool pn53x_decode_target_data(const byte_t* pbtRawData, size_t szDataLen, nfc_ch bool pn53x_InListPassiveTarget(const nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t szMaxTargets, const byte_t* pbtInitiatorData, const size_t szInitiatorDataLen, byte_t* pbtTargetsData, size_t* pszTargetsData); bool pn53x_InDeselect(const nfc_device_t* pnd, const uint8_t ui8Target); +bool pn53x_InRelease(nfc_device_t* pnd, const uint8_t ui8Target); #endif // __NFC_CHIPS_PN53X_H__ From d7c16d6d1a8f8317c31a7d40ec7a54195e280131 Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Sun, 8 Aug 2010 09:34:18 +0000 Subject: [PATCH 3/6] Factorise UART-relative macros definitions. --- libnfc/buses/uart.h | 26 ++++++++++++++++++++++++++ libnfc/drivers/arygon.c | 19 ------------------- libnfc/drivers/pn532_uart.c | 27 --------------------------- 3 files changed, 26 insertions(+), 46 deletions(-) diff --git a/libnfc/buses/uart.h b/libnfc/buses/uart.h index 87f9f27..8b0ea8a 100644 --- a/libnfc/buses/uart.h +++ b/libnfc/buses/uart.h @@ -43,8 +43,34 @@ #include #include #include + + // unistd.h is needed for usleep() fct. + #include + #define delay_ms( X ) usleep( X * 1000 ) #else #include + + #define snprintf _snprintf + #define strdup _strdup + #define delay_ms( X ) Sleep( X ) +#endif + +// Path to the serial port is OS-dependant. +// Try to guess what we should use. +// +// XXX: Some review from users cross-compiling is welcome! +#if defined(_WIN32) + #define SERIAL_STRING "COM" +//#elif defined(__APPLE__) +// TODO: find UART connection string for PN53X device on Mac OS X +// #define SERIAL_STRING "" +#elif defined (__FreeBSD__) || defined (__OpenBSD__) + // XXX: Not tested + #define SERIAL_STRING "/dev/cuau" +#elif defined (__linux__) + #define SERIAL_STRING "/dev/ttyUSB" +#else + #error "Can't determine serial string for your system" #endif // Define shortcut to types to make code more readable diff --git a/libnfc/drivers/arygon.c b/libnfc/drivers/arygon.c index 8c43f21..0ff9090 100644 --- a/libnfc/drivers/arygon.c +++ b/libnfc/drivers/arygon.c @@ -41,25 +41,6 @@ // Bus #include "uart.h" -#ifdef _WIN32 - #define SERIAL_STRING "COM" - #define snprintf _snprintf - #define strdup _strdup - #define delay_ms( X ) Sleep( X ) -#else - // unistd.h is needed for usleep() fct. - #include - #define delay_ms( X ) usleep( X * 1000 ) - - #ifdef __APPLE__ - // MacOS - #define SERIAL_STRING "/dev/tty.SLAB_USBtoUART" - #else - // *BSD, Linux and others POSIX systems - #define SERIAL_STRING "/dev/ttyUSB" - #endif -#endif - #define BUFFER_LENGTH 256 /** @def DEV_ARYGON_PROTOCOL_ARYGON_ASCII diff --git a/libnfc/drivers/pn532_uart.c b/libnfc/drivers/pn532_uart.c index 26c89a0..6359bcd 100644 --- a/libnfc/drivers/pn532_uart.c +++ b/libnfc/drivers/pn532_uart.c @@ -38,33 +38,6 @@ // Bus #include "uart.h" -#ifdef _WIN32 - #define SERIAL_STRING "COM" - #define snprintf _snprintf - #define strdup _strdup - #define delay_ms( X ) Sleep( X ) -#else - // unistd.h is needed for usleep() fct. - #include - #define delay_ms( X ) usleep( X * 1000 ) - - #ifdef __APPLE__ - // MacOS - // TODO: find UART connection string for PN53X device on Mac OS X - #define SERIAL_STRING "" - #elif defined(__FreeBSD__) - // XXX: Not tested - #define SERIAL_STRING "/dev/cuau" - #else - // Linux and maybe some operating systems - // FIXME: We'd rather have an #elif defined(__linux__) or something like - // that and an #else that triggers an error at compile time instead - // of "falling-back" on a value that is likely to not be suitable - // for most operating systems. - #define SERIAL_STRING "/dev/ttyUSB" - #endif -#endif - #define BUFFER_LENGTH 256 #define SERIAL_DEFAULT_PORT_SPEED 115200 From fd0efd4a62060373e01f28681a8e4bcc4ea7fba5 Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Tue, 10 Aug 2010 19:50:29 +0000 Subject: [PATCH 4/6] Fix build on Microsoft Windows. Windows users: I hate you in secret. --- examples/nfc-list.c | 8 +++++--- examples/nfc-mfultralight.c | 4 +++- examples/nfc-poll.c | 24 +++++++++++++----------- examples/nfc-utils.c | 4 ++-- libnfc/chips/pn53x.c | 3 ++- libnfc/drivers/pn53x_usb.c | 2 +- libnfc/nfc.c | 21 ++++++++++++++------- windows/Makefile | 7 ++++++- windows/win32/nfc.def | 9 ++++++--- 9 files changed, 52 insertions(+), 30 deletions(-) diff --git a/examples/nfc-list.c b/examples/nfc-list.c index e8e5171..3e00620 100644 --- a/examples/nfc-list.c +++ b/examples/nfc-list.c @@ -56,12 +56,13 @@ int main(int argc, const char* argv[]) size_t szTargetFound; size_t i; nfc_target_info_t nti; + nfc_device_desc_t *pnddDevices; // Display libnfc version acLibnfcVersion = nfc_version(); printf("%s use libnfc %s\n", argv[0], acLibnfcVersion); - nfc_device_desc_t *pnddDevices = parse_device_desc(argc, argv, &szDeviceFound); + pnddDevices = parse_device_desc(argc, argv, &szDeviceFound); if (argc > 1 && szDeviceFound == 0) { errx (1, "usage: %s [--device driver:port:speed]", argv[0]); @@ -106,6 +107,7 @@ int main(int argc, const char* argv[]) for (i = 0; i < szDeviceFound; i++) { + nfc_target_info_t anti[MAX_TARGET_COUNT]; pnd = nfc_connect(&(pnddDevices[i])); @@ -131,10 +133,10 @@ int main(int argc, const char* argv[]) printf("Connected to NFC reader: %s\n",pnd->acName); - nfc_target_info_t anti[MAX_TARGET_COUNT]; if (nfc_initiator_list_passive_targets(pnd, NM_ISO14443A_106, anti, MAX_TARGET_COUNT, &szTargetFound )) { + size_t n; printf("%zu ISO14443A passive targets was found:\n", szTargetFound); - for(size_t n=0; nnc == NC_PN531) { // PN531 doesn't support hardware polling (InAutoPoll) WARN ("%s", "PN531 doesn't support hardware polling."); continue; } printf ("PN53x will poll during %ld ms\n", (unsigned long) btPollNr * szTargetTypes * btPeriod * 150); - bool res = nfc_initiator_poll_targets (pnd, &nttMifare, 1, btPollNr, btPeriod, antTargets, &szTargetFound); + res = nfc_initiator_poll_targets (pnd, &nttMifare, 1, btPollNr, btPeriod, antTargets, &szTargetFound); if (res) { + uint8_t n; printf ("%ld target(s) have been found.\n", (unsigned long) szTargetFound); - for (uint8_t n = 0; n < szTargetFound; n++) { + for (n = 0; n < szTargetFound; n++) { printf ("T%d: targetType=%02x, ", n + 1, antTargets[n].ntt); printf ("targetData:\n"); print_nfc_iso14443a_info (antTargets[n].nti.nai); diff --git a/examples/nfc-utils.c b/examples/nfc-utils.c index 7664e7c..95b01e1 100644 --- a/examples/nfc-utils.c +++ b/examples/nfc-utils.c @@ -102,8 +102,8 @@ void print_nfc_iso14443a_info(const nfc_iso14443a_info_t nai) nfc_device_desc_t* parse_device_desc(int argc, const char *argv[], size_t* szFound) { nfc_device_desc_t* pndd = 0; - *szFound = 0; int arg; + *szFound = 0; // Get commandline options for (arg=1;arg arg+1) { + char buffer[256]; pndd = malloc(sizeof(nfc_device_desc_t)); - char buffer[256]; strncpy(buffer, argv[++arg], 256); // Driver. diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index 2431ea7..373adec 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -295,6 +295,7 @@ pn53x_InListPassiveTarget(const nfc_device_t* pnd, const byte_t* pbtInitiatorData, const size_t szInitiatorDataLen, byte_t* pbtTargetsData, size_t* pszTargetsData) { + size_t szRxLen; byte_t abtCmd[sizeof(pncmd_initiator_list_passive)]; memcpy(abtCmd,pncmd_initiator_list_passive,sizeof(pncmd_initiator_list_passive)); @@ -306,7 +307,7 @@ pn53x_InListPassiveTarget(const nfc_device_t* pnd, if (pbtInitiatorData) memcpy(abtCmd+4,pbtInitiatorData,szInitiatorDataLen); // Try to find a tag, call the tranceive callback function of the current device - size_t szRxLen = MAX_FRAME_LEN; + szRxLen = MAX_FRAME_LEN; // We can not use pn53x_transceive() because abtRx[0] gives no status info if(pnd->pdc->transceive(pnd->nds,abtCmd,4+szInitiatorDataLen,pbtTargetsData,&szRxLen)) { *pszTargetsData = szRxLen; diff --git a/libnfc/drivers/pn53x_usb.c b/libnfc/drivers/pn53x_usb.c index 7603c96..f33d060 100644 --- a/libnfc/drivers/pn53x_usb.c +++ b/libnfc/drivers/pn53x_usb.c @@ -240,6 +240,7 @@ bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, cons byte_t abtTx[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff" byte_t abtRx[BUFFER_LENGTH]; usb_spec_t* pus = (usb_spec_t*)nds; + uint8_t ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 }; // Packet length = data length (len) + checksum (1) + end of stream marker (1) abtTx[3] = szTxLen; @@ -280,7 +281,6 @@ bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, cons PRINT_HEX("RX", abtRx,ret); #endif - uint8_t ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 }; if ((ret != 6) || (memcmp (abtRx, ack_frame, 6))) { DBG ("%s", "===> No ACK!!!!!!"); return false; diff --git a/libnfc/nfc.c b/libnfc/nfc.c index 5770953..ecc0dca 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -33,6 +33,13 @@ #include +#ifdef _WIN32 + #include + + #define strdup _strdup + #define snprintf sprintf_s +#endif + #include "chips.h" #include "drivers.h" @@ -176,6 +183,7 @@ nfc_device_t* nfc_connect(nfc_device_desc_t* pndd) // Test if the connection was successful if (pnd != NULL) { + char* pcName; DBG("[%s] has been claimed.", pnd->acName); // Great we have claimed a device pnd->pdc = &(drivers_callbacks_list[uiDriver]); @@ -191,7 +199,7 @@ nfc_device_t* nfc_connect(nfc_device_desc_t* pndd) } // Add the firmware revision to the device name, PN531 gives 2 bytes info, but PN532 and PN533 gives 4 - char* pcName = strdup(pnd->acName); + pcName = strdup(pnd->acName); switch(pnd->nc) { case NC_PN531: snprintf(pnd->acName,DEVICE_NAME_LENGTH - 1,"%s - PN531 v%d.%d",pcName,abtFw[0],abtFw[1]); break; case NC_PN532: snprintf(pnd->acName,DEVICE_NAME_LENGTH - 1,"%s - PN532 v%d.%d (0x%02x)",pcName,abtFw[1],abtFw[2],abtFw[3]); break; @@ -423,6 +431,9 @@ nfc_initiator_select_passive_target(const nfc_device_t* pnd, byte_t abtInit[MAX_FRAME_LEN]; size_t szInitLen; + size_t szTargetsData; + byte_t abtTargetsData[MAX_FRAME_LEN]; + // Make sure we are dealing with a active device if (!pnd->bActive) return false; @@ -458,9 +469,6 @@ nfc_initiator_select_passive_target(const nfc_device_t* pnd, szInitLen = szInitDataLen; break; } - - size_t szTargetsData; - byte_t abtTargetsData[MAX_FRAME_LEN]; if(!pn53x_InListPassiveTarget(pnd, nmInitModulation, 1, abtInit, szInitLen, abtTargetsData, &szTargetsData)) return false; @@ -539,14 +547,13 @@ nfc_initiator_select_passive_target(const nfc_device_t* pnd, bool nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, nfc_target_info_t anti[], const size_t szTargets, size_t *pszTargetFound ) { - // Let the reader only try once to find a target - nfc_configure (pnd, NDO_INFINITE_SELECT, false); - nfc_target_info_t nti; bool bCollisionDetected = false; size_t szTargetFound = 0; + // Let the reader only try once to find a target + nfc_configure (pnd, NDO_INFINITE_SELECT, false); while (nfc_initiator_select_passive_target (pnd, nmInitModulation, NULL, 0, &nti)) { nfc_initiator_deselect_target(pnd); diff --git a/windows/Makefile b/windows/Makefile index cd1ad7b..5b7788c 100644 --- a/windows/Makefile +++ b/windows/Makefile @@ -70,9 +70,11 @@ NFCIP_TARGET_OBJ=obj\nfcip-target.obj \ obj\nfc-utils.obj NFC_MFCLASSIC_OBJ=obj\nfc-mfclassic.obj \ + obj\mifare.obj \ obj\nfc-utils.obj NFC_MFULTRALIGHT_OBJ=obj\nfc-mfultralight.obj \ + obj\mifare.obj \ obj\nfc-utils.obj all: obj bin $(LIBNFC_DLL) $(NFC_LIST) $(NFC_POLL) $(NFC_RELAY) $(NFCIP_INITIATOR) $(NFCIP_TARGET) $(NFC_ANTICOL) $(NFC_EMULATE) $(NFC_MFCLASSIC) $(NFC_MFULTRALIGHT) @@ -157,6 +159,9 @@ $(NFC_MFULTRALIGHT): $(NFC_MFULTRALIGHT_OBJ) $(LIBNFC_DLL) bin\$(DLLNAME).lib ob if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;#1 if exist $@.manifest del $@.manifest +obj\mifare.obj: ..\examples\mifare.c + $(CC) /c $(CC_OUT_OBJ)$@ $(CFLAGS) ..\examples\mifare.c + obj\nfc-relay.obj: ..\examples\nfc-relay.c $(CC) /c $(CC_OUT_OBJ)$@ $(CFLAGS) ..\examples\nfc-relay.c @@ -259,4 +264,4 @@ install: all cd .. - \ No newline at end of file + diff --git a/windows/win32/nfc.def b/windows/win32/nfc.def index 7688af4..a71ac40 100644 --- a/windows/win32/nfc.def +++ b/windows/win32/nfc.def @@ -7,14 +7,14 @@ EXPORTS nfc_disconnect nfc_configure nfc_initiator_init - nfc_initiator_select_tag + nfc_initiator_select_passive_target + nfc_initiator_list_passive_targets nfc_initiator_select_dep_target - nfc_initiator_deselect_tag + nfc_initiator_deselect_target nfc_initiator_poll_targets nfc_initiator_transceive_bits nfc_initiator_transceive_bytes nfc_initiator_transceive_dep_bytes - nfc_initiator_mifare_cmd nfc_target_init nfc_target_receive_bits nfc_target_receive_bytes @@ -26,3 +26,6 @@ EXPORTS iso14443a_crc append_iso14443a_crc nfc_version +; FIXME: Lines bellow SUCKS! + pn53x_transceive + pncmd_initiator_exchange_data From eece4963510430f4b5782b03f2104079a225cb62 Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Tue, 10 Aug 2010 21:00:08 +0000 Subject: [PATCH 5/6] Use nfc_initiator_transceive_dep_bytes() instead of pn53x_transceive() in example. --- examples/mifare.c | 16 +++++++--------- windows/win32/nfc.def | 1 - 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/examples/mifare.c b/examples/mifare.c index 1deb523..ed48b88 100644 --- a/examples/mifare.c +++ b/examples/mifare.c @@ -2,9 +2,9 @@ #include -#include "chips/pn53x.h" +#include -extern const byte_t pncmd_initiator_exchange_data [265]; +#include "chips/pn53x.h" /** * @brief Execute a MIFARE Classic Command @@ -24,15 +24,13 @@ bool nfc_initiator_mifare_cmd(const nfc_device_t* pnd, const mifare_cmd mc, cons byte_t abtRx[MAX_FRAME_LEN]; size_t szRxLen; size_t szParamLen; - byte_t abtCmd[sizeof(pncmd_initiator_exchange_data)]; - memcpy(abtCmd,pncmd_initiator_exchange_data,sizeof(pncmd_initiator_exchange_data)); + byte_t abtCmd[265]; // Make sure we are dealing with a active device if (!pnd->bActive) return false; - abtCmd[2] = 0x01; // Use first target/card - abtCmd[3] = mc; // The MIFARE Classic command - abtCmd[4] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff) + abtCmd[0] = mc; // The MIFARE Classic command + abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff) switch (mc) { @@ -67,10 +65,10 @@ bool nfc_initiator_mifare_cmd(const nfc_device_t* pnd, const mifare_cmd mc, cons } // When available, copy the parameter bytes - if (szParamLen) memcpy(abtCmd+5,(byte_t*)pmp,szParamLen); + if (szParamLen) memcpy(abtCmd+2,(byte_t*)pmp,szParamLen); // Fire the mifare command - if (!pn53x_transceive(pnd,abtCmd,5+szParamLen,abtRx,&szRxLen)) return false; + if (!nfc_initiator_transceive_dep_bytes(pnd,abtCmd,2+szParamLen,abtRx,&szRxLen)) return false; // When we have executed a read command, copy the received bytes into the param if (mc == MC_READ && szRxLen == 17) memcpy(pmp->mpd.abtData,abtRx+1,16); diff --git a/windows/win32/nfc.def b/windows/win32/nfc.def index a71ac40..6753b20 100644 --- a/windows/win32/nfc.def +++ b/windows/win32/nfc.def @@ -27,5 +27,4 @@ EXPORTS append_iso14443a_crc nfc_version ; FIXME: Lines bellow SUCKS! - pn53x_transceive pncmd_initiator_exchange_data From bda739eb8fbed29e9790c0a7bd725c5df0ae4f64 Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Tue, 10 Aug 2010 21:02:26 +0000 Subject: [PATCH 6/6] Hey! r509 also fixed that! --- windows/win32/nfc.def | 2 -- 1 file changed, 2 deletions(-) diff --git a/windows/win32/nfc.def b/windows/win32/nfc.def index 6753b20..ba83eaf 100644 --- a/windows/win32/nfc.def +++ b/windows/win32/nfc.def @@ -26,5 +26,3 @@ EXPORTS iso14443a_crc append_iso14443a_crc nfc_version -; FIXME: Lines bellow SUCKS! - pncmd_initiator_exchange_data