diff --git a/README.md b/README.md index 1f3f8e7..775a46d 100644 --- a/README.md +++ b/README.md @@ -219,7 +219,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 diff --git a/contrib/win32/libnfc/buses/uart.c b/contrib/win32/libnfc/buses/uart.c index ba7ddfe..982e18c 100644 --- a/contrib/win32/libnfc/buses/uart.c +++ b/contrib/win32/libnfc/buses/uart.c @@ -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) diff --git a/libnfc/buses/i2c.c b/libnfc/buses/i2c.c index dc1ad1f..52180e6 100644 --- a/libnfc/buses/i2c.c +++ b/libnfc/buses/i2c.c @@ -47,7 +47,11 @@ #include #include #include +#ifdef __APPLE__ +#include +#else #include +#endif #include #include #include diff --git a/libnfc/buses/spi.c b/libnfc/buses/spi.c index 0e68f9b..774d17d 100644 --- a/libnfc/buses/spi.c +++ b/libnfc/buses/spi.c @@ -49,7 +49,11 @@ #include #include #include +#ifdef __APPLE__ +#include +#else #include +#endif #include #include diff --git a/libnfc/buses/uart.c b/libnfc/buses/uart.c index ffe64aa..08ff9ce 100644 --- a/libnfc/buses/uart.c +++ b/libnfc/buses/uart.c @@ -47,7 +47,11 @@ #include #include #include +#ifdef __APPLE__ +#include +#else #include +#endif #include #include @@ -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 @@ -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 ** diff --git a/libnfc/buses/uart.h b/libnfc/buses/uart.h index 39d8d2f..485ccf3 100644 --- a/libnfc/buses/uart.h +++ b/libnfc/buses/uart.h @@ -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);