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

Fix PN532 UART support + macOS support #633

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ Readers known to work:

These readers are support by CCID since v1.4.25, make sure your CCID driver version higher or equal to 1.4.25.

On MacOS, you can check your CCID version with the following command, and if required, you can install latest CCID driver from [https://github.com/martinpaljak/osx-ccid-installer/releases](https://github.com/martinpaljak/osx-ccid-installer/releases)
On macOS, you can check your CCID version with the following command, and if required, you can install latest CCID driver from [https://github.com/martinpaljak/osx-ccid-installer/releases](https://github.com/martinpaljak/osx-ccid-installer/releases)

```
grep -A 1 CFBundleShortVersionString /usr/local/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
Expand Down
2 changes: 1 addition & 1 deletion contrib/win32/libnfc/buses/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ uart_send(serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout)
}
if (!dwTxLen)
return NFC_EIO;
return 0;
return NFC_SUCCESS;
}

BOOL is_port_available(int nPort)
Expand Down
4 changes: 4 additions & 0 deletions libnfc/buses/i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#ifdef __APPLE__
#include <sys/termios.h>
#else
#include <termios.h>
#endif
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
Expand Down
4 changes: 4 additions & 0 deletions libnfc/buses/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#ifdef __APPLE__
#include <sys/termios.h>
#else
#include <termios.h>
#endif
#include <unistd.h>

#include <nfc/nfc.h>
Expand Down
46 changes: 46 additions & 0 deletions libnfc/buses/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#ifdef __APPLE__
#include <sys/termios.h>
#else
#include <termios.h>
#endif
#include <unistd.h>
#include <stdlib.h>

Expand Down Expand Up @@ -95,6 +99,19 @@ const char *serial_ports_device_radix[] = { "ttyUSB", "ttyS", "ttyACM", "ttyAMA"
// Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct
# define CCLAIMED 0x80000000

// If macOS and still haven't detected required baud rates, set them as we do have support for some
#ifdef __APPLE__
#ifndef B57600
#define B57600 57600
#endif
#ifndef B115200
#define B115200 115200
#endif
#ifndef B230400
#define B230400 230400
#endif
#endif

struct serial_port_unix {
int fd; // Serial port file descriptor
struct termios termios_backup; // Terminal info before using the port
Expand Down Expand Up @@ -377,10 +394,39 @@ uart_send(serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout)
{
(void) timeout;
LOG_HEX(LOG_GROUP, "TX", pbtTx, szTx);

#ifndef __APPLE__
if ((int) szTx == write(UART_DATA(sp)->fd, pbtTx, szTx))
return NFC_SUCCESS;
else
return NFC_EIO;
#else
// macOS's termios write() to a uart is async so we need to determine how to make it sync
// see https://github.com/nfc-tools/libnfc/pull/633
// there is probably a proper way to do this, if so, please share!
return uart_send_single(sp, pbtTx, szTx, timeout);
#endif
}

/**
* @brief Send \a pbtTx content to UART one byte at a time with a delay (to support macOS' async write)
*
* @return 0 on success, otherwise a driver error is returned
*/
int
uart_send_single(serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout)
{
(void) timeout;

for (int i = 0; i < szTx; i++)
{
if (write(UART_DATA(sp)->fd, pbtTx+i, 1) != 1)
return NFC_EIO;

usleep(9); // sleep for ceil(1_000_000us / 115200baud) = 9us
}

return NFC_SUCCESS;
}

char **
Expand Down
1 change: 1 addition & 0 deletions libnfc/buses/uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ 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);
int uart_send_single(serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout);

char **uart_list_ports(void);

Expand Down