diff --git a/libnfc/buses/uart.h b/libnfc/buses/uart.h index 9508782..5d52305 100644 --- a/libnfc/buses/uart.h +++ b/libnfc/buses/uart.h @@ -42,6 +42,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_set_speed (serial_port sp, const uint32_t uiPortSpeed); uint32_t uart_get_speed (const serial_port sp); diff --git a/libnfc/buses/uart_posix.c b/libnfc/buses/uart_posix.c index 0698e5a..3f175da 100644 --- a/libnfc/buses/uart_posix.c +++ b/libnfc/buses/uart_posix.c @@ -100,9 +100,6 @@ uart_open (const char *pcPortName) sp->tiNew.c_cc[VMIN] = 0; // block until n bytes are received sp->tiNew.c_cc[VTIME] = 0; // block until a timer expires (n * 100 mSec.) - // This line seems to produce absolutely no effect on my system (GNU/Linux 2.6.35) - tcflush (sp->fd, TCIFLUSH); - if (tcsetattr (sp->fd, TCSANOW, &sp->tiNew) == -1) { uart_close (sp); return INVALID_SERIAL_PORT; @@ -110,6 +107,29 @@ uart_open (const char *pcPortName) return sp; } +void +uart_flush_input (serial_port sp) +{ + // This line seems to produce absolutely no effect on my system (GNU/Linux 2.6.35) + tcflush (((serial_port_unix *) sp)->fd, TCIFLUSH); + // So, I wrote this byte-eater + // Retrieve the count of the incoming bytes + int available_bytes_count = 0; + int res; + res = ioctl (((serial_port_unix *) sp)->fd, FIONREAD, &available_bytes_count); + if (res != 0) { + return; + } + if (available_bytes_count == 0) { + return; + } + char* rx = malloc (available_bytes_count); + // There is something available, read the data + res = read (((serial_port_unix *) sp)->fd, rx, available_bytes_count); + DBG ("%d bytes have eatten.", available_bytes_count); + free (rx); +} + void uart_set_speed (serial_port sp, const uint32_t uiPortSpeed) { diff --git a/libnfc/buses/uart_win32.c b/libnfc/buses/uart_win32.c index 18685fa..8e34d37 100644 --- a/libnfc/buses/uart_win32.c +++ b/libnfc/buses/uart_win32.c @@ -87,6 +87,12 @@ uart_close (const serial_port sp) free (sp); } +void +uart_flush_input (const serial_port sp) +{ + // TODO: Implement me +} + void uart_set_speed (serial_port sp, const uint32_t uiPortSpeed) { diff --git a/libnfc/drivers/arygon.c b/libnfc/drivers/arygon.c index f724346..1a232f1 100644 --- a/libnfc/drivers/arygon.c +++ b/libnfc/drivers/arygon.c @@ -111,6 +111,8 @@ arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev DBG ("Trying to find ARYGON device on serial port: %s at %d bauds.", pcPort, ARYGON_DEFAULT_SPEED); 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_set_speed (sp, ARYGON_DEFAULT_SPEED); nfc_device_t *pnd = nfc_device_new (); @@ -167,6 +169,8 @@ arygon_connect (const nfc_device_desc_t * pndd) if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL; + // We need to flush input to be sure first reply does not comes from older byte transceive + uart_flush_input (sp); uart_set_speed (sp, pndd->uiSpeed); // We have a connection @@ -231,6 +235,9 @@ arygon_disconnect (nfc_device_t * pnd) bool arygon_tama_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData) { + // Before sending anything, we need to discard from any junk bytes + uart_flush_input (DRIVER_DATA(pnd)->port); + byte_t abtFrame[ARYGON_TX_BUFFER_LEN] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "0x32 0x00 0x00 0xff" size_t szFrame = 0; diff --git a/libnfc/drivers/pn532_uart.c b/libnfc/drivers/pn532_uart.c index 30eda51..aa76264 100644 --- a/libnfc/drivers/pn532_uart.c +++ b/libnfc/drivers/pn532_uart.c @@ -90,6 +90,8 @@ pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps DBG ("Trying to find PN532 device on serial port: %s at %d bauds.", pcPort, PN532_UART_DEFAULT_SPEED); 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); // Serial port claimed but we need to check if a PN532_UART is connected. uart_set_speed (sp, PN532_UART_DEFAULT_SPEED); @@ -154,6 +156,8 @@ pn532_uart_connect (const nfc_device_desc_t * pndd) if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL; + // We need to flush input to be sure first reply does not comes from older byte transceive + uart_flush_input (sp); uart_set_speed (sp, pndd->uiSpeed); // We have a connection @@ -219,6 +223,9 @@ pn532_uart_wakeup (nfc_device_t * pnd) bool pn532_uart_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData) { + // Before sending anything, we need to discard from any junk bytes + uart_flush_input (DRIVER_DATA(pnd)->port); + switch (CHIP_DATA(pnd)->power_mode) { case LOWVBAT: { /** PN532C106 wakeup. */