diff --git a/libnfc/buses/uart.c b/libnfc/buses/uart.c index c2e67af..0c6227b 100644 --- a/libnfc/buses/uart.c +++ b/libnfc/buses/uart.c @@ -57,6 +57,22 @@ #define LOG_GROUP NFC_LOG_GROUP_COM #define LOG_CATEGORY "libnfc.bus.uart" +#ifndef _WIN32 +// Needed by sleep() under Unix +# include +# include +# define msleep(x) do { \ + struct timespec xsleep; \ + xsleep.tv_sec = x / 1000; \ + xsleep.tv_nsec = (x - xsleep.tv_sec * 1000) * 1000 * 1000; \ + nanosleep(&xsleep, NULL); \ + } while (0) +#else +// Needed by Sleep() under Windows +# include +# define msleep Sleep +#endif + # if defined(__APPLE__) const char *serial_ports_device_radix[] = { "tty.SLAB_USBtoUART", "tty.usbserial-", NULL }; # elif defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__FreeBSD_kernel__) @@ -122,8 +138,16 @@ uart_open(const char *pcPortName) } void -uart_flush_input(serial_port sp) +uart_flush_input(serial_port sp, bool wait) { + // flush commands may seem to be without effect + // if asked too quickly after previous event, cf comments below + // therefore a "wait" argument allows now to wait before flushing + // I believe that now the byte-eater part is not required anymore --Phil + if (wait) { + msleep(50); // 50 ms + } + // This line seems to produce absolutely no effect on my system (GNU/Linux 2.6.35) tcflush(UART_DATA(sp)->fd, TCIFLUSH); // So, I wrote this byte-eater diff --git a/libnfc/buses/uart.h b/libnfc/buses/uart.h index ea818d8..49b822a 100644 --- a/libnfc/buses/uart.h +++ b/libnfc/buses/uart.h @@ -49,7 +49,7 @@ 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); +void uart_flush_input(const serial_port sp, bool wait); void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed); uint32_t uart_get_speed(const serial_port sp); diff --git a/libnfc/drivers/acr122s.c b/libnfc/drivers/acr122s.c index 6fcbf8e..2f6ec1d 100644 --- a/libnfc/drivers/acr122s.c +++ b/libnfc/drivers/acr122s.c @@ -426,7 +426,7 @@ acr122s_scan(const nfc_context *context, nfc_connstring connstrings[], const siz if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) { // We need to flush input to be sure first reply does not comes from older byte transceive - uart_flush_input(sp); + uart_flush_input(sp, true); uart_set_speed(sp, ACR122S_DEFAULT_SPEED); nfc_connstring connstring; @@ -578,7 +578,7 @@ acr122s_open(const nfc_context *context, const nfc_connstring connstring) return NULL; } - uart_flush_input(sp); + uart_flush_input(sp, true); uart_set_speed(sp, ndd.speed); pnd = nfc_device_new(context, connstring); @@ -659,7 +659,7 @@ acr122s_open(const nfc_context *context, const nfc_connstring connstring) static int acr122s_send(nfc_device *pnd, const uint8_t *buf, const size_t buf_len, int timeout) { - uart_flush_input(DRIVER_DATA(pnd)->port); + uart_flush_input(DRIVER_DATA(pnd)->port, false); uint8_t cmd[MAX_FRAME_SIZE]; if (! acr122s_build_frame(pnd, cmd, sizeof(cmd), 0, 0, buf, buf_len, 1)) { diff --git a/libnfc/drivers/arygon.c b/libnfc/drivers/arygon.c index 3d99f61..1ff38f4 100644 --- a/libnfc/drivers/arygon.c +++ b/libnfc/drivers/arygon.c @@ -113,7 +113,7 @@ arygon_scan(const nfc_context *context, nfc_connstring connstrings[], const size if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) { // We need to flush input to be sure first reply does not comes from older byte transceive - uart_flush_input(sp); + uart_flush_input(sp, true); uart_set_speed(sp, ARYGON_DEFAULT_SPEED); nfc_connstring connstring; @@ -266,7 +266,7 @@ arygon_open(const nfc_context *context, const nfc_connstring connstring) } // We need to flush input to be sure first reply does not comes from older byte transceive - uart_flush_input(sp); + uart_flush_input(sp, true); uart_set_speed(sp, ndd.speed); // We have a connection @@ -340,7 +340,7 @@ arygon_tama_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, i { int res = 0; // Before sending anything, we need to discard from any junk bytes - uart_flush_input(DRIVER_DATA(pnd)->port); + uart_flush_input(DRIVER_DATA(pnd)->port, false); uint8_t abtFrame[ARYGON_TX_BUFFER_LEN] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "0x32 0x00 0x00 0xff" diff --git a/libnfc/drivers/pn532_uart.c b/libnfc/drivers/pn532_uart.c index 9561b89..12794af 100644 --- a/libnfc/drivers/pn532_uart.c +++ b/libnfc/drivers/pn532_uart.c @@ -86,7 +86,7 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) { // We need to flush input to be sure first reply does not comes from older byte transceive - uart_flush_input(sp); + uart_flush_input(sp, true); // Serial port claimed but we need to check if a PN532_UART is opened. uart_set_speed(sp, PN532_UART_DEFAULT_SPEED); @@ -237,7 +237,7 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring) return NULL; } // We need to flush input to be sure first reply does not comes from older byte transceive - uart_flush_input(sp); + uart_flush_input(sp, true); uart_set_speed(sp, ndd.speed); // We have a connection @@ -315,7 +315,7 @@ pn532_uart_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, in { int res = 0; // Before sending anything, we need to discard from any junk bytes - uart_flush_input(DRIVER_DATA(pnd)->port); + uart_flush_input(DRIVER_DATA(pnd)->port, false); switch (CHIP_DATA(pnd)->power_mode) { case LOWVBAT: { @@ -494,7 +494,7 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in // The PN53x command is done and we successfully received the reply return len; error: - uart_flush_input(DRIVER_DATA(pnd)->port); + uart_flush_input(DRIVER_DATA(pnd)->port, true); return pnd->last_error; }