diff --git a/contrib/win32/libnfc/buses/uart.c b/contrib/win32/libnfc/buses/uart.c index f0bbe78..982e18c 100644 --- a/contrib/win32/libnfc/buses/uart.c +++ b/contrib/win32/libnfc/buses/uart.c @@ -240,30 +240,6 @@ uart_send(serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout) return NFC_SUCCESS; } -/** - * @brief Send \a pbtTx content to UART one byte at a time - * - * @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; - int ret; - for (int i = 0; i < szTx; i++) - { - ret = uart_send(sp, pbtTx+i, 1, timeout); - - // if we didn't transmit byte, bail out - if (ret != NFC_SUCCESS) - return ret; - - delay_ms(1); // ceil(1_000_000us / 115200baud) = 9us but no usleep on windows - } - - return NFC_SUCCESS; -} - BOOL is_port_available(int nPort) { TCHAR szPort[15]; diff --git a/libnfc/buses/uart.c b/libnfc/buses/uart.c index e4d34c0..08ff9ce 100644 --- a/libnfc/buses/uart.c +++ b/libnfc/buses/uart.c @@ -394,14 +394,22 @@ 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 + * @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 */ @@ -409,14 +417,11 @@ int uart_send_single(serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout) { (void) timeout; - int ret; + for (int i = 0; i < szTx; i++) { - ret = uart_send(sp, pbtTx+i, 1, timeout); - - // if we didn't transmit byte, bail out - if (ret != NFC_SUCCESS) - return ret; + if (write(UART_DATA(sp)->fd, pbtTx+i, 1) != 1) + return NFC_EIO; usleep(9); // sleep for ceil(1_000_000us / 115200baud) = 9us } diff --git a/libnfc/drivers/pn532_uart.c b/libnfc/drivers/pn532_uart.c index dae0242..d82051d 100644 --- a/libnfc/drivers/pn532_uart.c +++ b/libnfc/drivers/pn532_uart.c @@ -304,7 +304,7 @@ pn532_uart_wakeup(nfc_device *pnd) { /* High Speed Unit (HSU) wake up consist to send 0x55 and wait a "long" delay for PN532 being wakeup. */ const uint8_t pn532_wakeup_preamble[] = { 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - int res = uart_send_single(DRIVER_DATA(pnd)->port, pn532_wakeup_preamble, sizeof(pn532_wakeup_preamble), 0); + int res = uart_send(DRIVER_DATA(pnd)->port, pn532_wakeup_preamble, sizeof(pn532_wakeup_preamble), 0); CHIP_DATA(pnd)->power_mode = NORMAL; // PN532 should now be awake return res; } @@ -348,7 +348,7 @@ pn532_uart_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, in return pnd->last_error; } - res = uart_send_single(DRIVER_DATA(pnd)->port, abtFrame, szFrame, timeout); + res = uart_send(DRIVER_DATA(pnd)->port, abtFrame, szFrame, timeout); if (res != 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)"); pnd->last_error = res; @@ -507,7 +507,7 @@ pn532_uart_ack(nfc_device *pnd) return res; } } - return (uart_send_single(DRIVER_DATA(pnd)->port, pn53x_ack_frame, sizeof(pn53x_ack_frame), 0)); + return (uart_send(DRIVER_DATA(pnd)->port, pn53x_ack_frame, sizeof(pn53x_ack_frame), 0)); } static int