Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] MFRC522 support #300

Closed
wants to merge 16 commits into from
Closed
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*.la
*.lo
*.o
*.stackdump
*~
Doxyfile
INSTALL
Expand Down
7 changes: 7 additions & 0 deletions cmake/modules/LibnfcDrivers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ELSE(WIN32)
ENDIF(WIN32)
SET(LIBNFC_DRIVER_PN532_UART ON CACHE BOOL "Enable PN532 UART support (Use serial port)")
SET(LIBNFC_DRIVER_PN53X_USB ON CACHE BOOL "Enable PN531 and PN531 USB support (Depends on libusb)")
SET(LIBNFC_DRIVER_RC522_UART ON CACHE BOOL "Enable MFRC522/FM17222 UART support (Use serial port)")

IF(LIBNFC_DRIVER_ACR122_PCSC)
FIND_PACKAGE(PCSC REQUIRED)
Expand Down Expand Up @@ -61,4 +62,10 @@ IF(LIBNFC_DRIVER_PN53X_USB)
SET(USB_REQUIRED TRUE)
ENDIF(LIBNFC_DRIVER_PN53X_USB)

IF(LIBNFC_DRIVER_RC522_UART)
ADD_DEFINITIONS("-DDRIVER_RC522_UART_ENABLED")
SET(DRIVERS_SOURCES ${DRIVERS_SOURCES} "drivers/rc522_uart")
SET(UART_REQUIRED TRUE)
ENDIF(LIBNFC_DRIVER_RC522_UART)

INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/libnfc/drivers)
22 changes: 11 additions & 11 deletions examples/nfc-anticol.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ transmit_bits(const uint8_t *pbtTx, const size_t szTxBits)


static bool
transmit_bytes(const uint8_t *pbtTx, const size_t szTx)
transmit_bytes(const uint8_t *pbtTx, const size_t szTx, bool wantsReply)
{
uint32_t cycles = 0;
// Show transmitted command
Expand All @@ -124,13 +124,13 @@ transmit_bytes(const uint8_t *pbtTx, const size_t szTx)
int res;
// Transmit the command bytes
if (timed) {
if ((res = nfc_initiator_transceive_bytes_timed(pnd, pbtTx, szTx, abtRx, sizeof(abtRx), &cycles)) < 0)
if ((res = nfc_initiator_transceive_bytes_timed(pnd, pbtTx, szTx, abtRx, wantsReply ? sizeof(abtRx) : 0, &cycles)) < 0)
return false;
if ((!quiet_output) && (res > 0)) {
printf("Response after %u cycles\n", cycles);
}
} else {
if ((res = nfc_initiator_transceive_bytes(pnd, pbtTx, szTx, abtRx, sizeof(abtRx), 0)) < 0)
if ((res = nfc_initiator_transceive_bytes(pnd, pbtTx, szTx, abtRx, wantsReply ? sizeof(abtRx) : 0, -1)) < 0)
return false;
}
szRx = res;
Expand Down Expand Up @@ -235,7 +235,7 @@ main(int argc, char *argv[])
memcpy(abtAtqa, abtRx, 2);

// Anti-collision
transmit_bytes(abtSelectAll, 2);
transmit_bytes(abtSelectAll, 2, true);

// Check answer
if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) {
Expand All @@ -248,7 +248,7 @@ main(int argc, char *argv[])
//Prepare and send CL1 Select-Command
memcpy(abtSelectTag + 2, abtRx, 5);
iso14443a_crc_append(abtSelectTag, 7);
transmit_bytes(abtSelectTag, 9);
transmit_bytes(abtSelectTag, 9, true);
abtSak = abtRx[0];

// Test if we are dealing with a CL2
Expand All @@ -267,7 +267,7 @@ main(int argc, char *argv[])
abtSelectAll[0] = 0x95;

// Anti-collision
transmit_bytes(abtSelectAll, 2);
transmit_bytes(abtSelectAll, 2, true);

// Check answer
if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) {
Expand All @@ -281,7 +281,7 @@ main(int argc, char *argv[])
abtSelectTag[0] = 0x95;
memcpy(abtSelectTag + 2, abtRx, 5);
iso14443a_crc_append(abtSelectTag, 7);
transmit_bytes(abtSelectTag, 9);
transmit_bytes(abtSelectTag, 9, true);
abtSak = abtRx[0];

// Test if we are dealing with a CL3
Expand All @@ -298,7 +298,7 @@ main(int argc, char *argv[])

// Prepare and send CL3 AC-Command
abtSelectAll[0] = 0x97;
transmit_bytes(abtSelectAll, 2);
transmit_bytes(abtSelectAll, 2, true);

// Check answer
if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) {
Expand All @@ -312,7 +312,7 @@ main(int argc, char *argv[])
abtSelectTag[0] = 0x97;
memcpy(abtSelectTag + 2, abtRx, 5);
iso14443a_crc_append(abtSelectTag, 7);
transmit_bytes(abtSelectTag, 9);
transmit_bytes(abtSelectTag, 9, true);
abtSak = abtRx[0];
}
}
Expand All @@ -323,15 +323,15 @@ main(int argc, char *argv[])
}
if ((abtRx[0] & SAK_FLAG_ATS_SUPPORTED) || force_rats) {
iso14443a_crc_append(abtRats, 2);
if (transmit_bytes(abtRats, 4)) {
if (transmit_bytes(abtRats, 4, true)) {
memcpy(abtAts, abtRx, szRx);
szAts = szRx;
}
}

// Done, halt the tag now
iso14443a_crc_append(abtHalt, 2);
transmit_bytes(abtHalt, 4);
transmit_bytes(abtHalt, 4, false);

printf("\nFound tag with\n UID: ");
switch (szCL) {
Expand Down
4 changes: 3 additions & 1 deletion libnfc/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ libnfc_la_SOURCES = \
log-internal.h \
mirror-subr.h \
nfc-internal.h \
target-subr.h
target-subr.h \
timing.h \
timing.c

libnfc_la_LDFLAGS = -no-undefined -version-info 5:1:0 -export-symbols-regex '^nfc_|^iso14443a_|^iso14443b_|^str_nfc_|pn53x_transceive|pn532_SAMConfiguration|pn53x_read_register|pn53x_write_register'
libnfc_la_CFLAGS = @DRIVERS_CFLAGS@
Expand Down
37 changes: 28 additions & 9 deletions libnfc/buses/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,11 @@ uart_open(const char *pcPortName)
uart_close_ext(sp, true);
return INVALID_SERIAL_PORT;
}

return sp;
}

void
int
uart_flush_input(serial_port sp, bool wait)
{
// flush commands may seem to be without effect
Expand All @@ -156,34 +157,37 @@ uart_flush_input(serial_port sp, bool wait)
}

// This line seems to produce absolutely no effect on my system (GNU/Linux 2.6.35)
tcflush(UART_DATA(sp)->fd, TCIFLUSH);
if (tcflush(UART_DATA(sp)->fd, TCIFLUSH)) {
return NFC_EIO;
}
// So, I wrote this byte-eater
// Retrieve the count of the incoming bytes
int available_bytes_count = 0;
int res;
res = ioctl(UART_DATA(sp)->fd, FIONREAD, &available_bytes_count);
if (res != 0) {
return;
return NFC_EIO;
}
if (available_bytes_count == 0) {
return;
return NFC_SUCCESS;
}
char *rx = malloc(available_bytes_count);
if (!rx) {
perror("malloc");
return;
return NFC_ESOFT;
}
// There is something available, read the data
if (read(UART_DATA(sp)->fd, rx, available_bytes_count) < 0) {
perror("uart read");
free(rx);
return;
return NFC_EIO;
}
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%d bytes have eaten.", available_bytes_count);
free(rx);
return NFC_SUCCESS;
}

void
int
uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
{
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Serial port speed requested to be set to %d baud.", uiPortSpeed);
Expand Down Expand Up @@ -224,15 +228,17 @@ uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
default:
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to set serial port speed to %d baud. Speed value must be one of those defined in termios(3).",
uiPortSpeed);
return;
return NFC_ESOFT;
};

// Set port speed (Input and Output)
cfsetispeed(&(UART_DATA(sp)->termios_new), stPortSpeed);
cfsetospeed(&(UART_DATA(sp)->termios_new), stPortSpeed);
if (tcsetattr(UART_DATA(sp)->fd, TCSADRAIN, &(UART_DATA(sp)->termios_new)) == -1) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to apply new speed settings.");
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to apply new speed settings.");
return NFC_EIO;
}
return NFC_SUCCESS;
}

uint32_t
Expand Down Expand Up @@ -430,3 +436,16 @@ uart_list_ports(void)

return res;
}

void
uart_list_free(char ** acPorts)
{
char *acPort;
size_t iDevice = 0;

while ((acPort = acPorts[iDevice++])) {
free((void *)acPort);
}

free(acPorts);
}
5 changes: 3 additions & 2 deletions libnfc/buses/uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ typedef void *serial_port;

serial_port uart_open(const char *pcPortName);
void uart_close(const serial_port sp);
void uart_flush_input(const serial_port sp, bool wait);
int uart_flush_input(const serial_port sp, bool wait);

void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed);
int uart_set_speed(serial_port sp, const uint32_t uiPortSpeed);
uint32_t uart_get_speed(const serial_port sp);

int uart_receive(serial_port sp, uint8_t *pbtRx, const size_t szRx, void *abort_p, int timeout);
int uart_send(serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout);

char **uart_list_ports(void);
void uart_list_free(char **acPorts);

#endif // __NFC_BUS_UART_H__
2 changes: 1 addition & 1 deletion libnfc/chips/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
AM_CPPFLAGS = $(all_includes) $(LIBNFC_CFLAGS)

noinst_LTLIBRARIES = libnfcchips.la
libnfcchips_la_SOURCES = pn53x.c pn53x.h pn53x-internal.h
libnfcchips_la_SOURCES = pn53x.c pn53x.h pn53x-internal.h rc522.c rc522.h rc522-internal.h
libnfcchips_la_CFLAGS = -I$(top_srcdir)/libnfc

Loading