#include <sys/syslimits.h>
#endif
#ifdef __linux__
+#ifdef HAVE_LIBUDEV
#include "libudev.h"
+#endif
+#ifndef __ANDROID__
#include "linux/serial.h"
+#endif
#include "linux_termios.h"
/* TCGETX/TCSETX is not available everywhere. */
#define RETURN_OK() RETURN_CODE(SP_OK);
#define RETURN_ERROR(err, msg) do { DEBUG_ERROR(err, msg); return err; } while (0)
#define RETURN_FAIL(msg) do { DEBUG_FAIL(msg); return SP_ERR_FAIL; } while (0)
-#define RETURN_VALUE(fmt, x) do { DEBUG("%s returning " fmt, __func__, x); return x; } while (0)
+#define RETURN_VALUE(fmt, x) do { \
+ typeof(x) _x = x; \
+ DEBUG("%s returning " fmt, __func__, _x); \
+ return _x; \
+} while (0)
#define SET_ERROR(val, err, msg) do { DEBUG_ERROR(err, msg); val = err; } while (0)
#define SET_FAIL(val, msg) do { DEBUG_FAIL(msg); val = SP_ERR_FAIL; } while (0)
#define TRACE(fmt, ...) DEBUG("%s(" fmt ") called", __func__, ##__VA_ARGS__)
IOObjectRelease(iter);
out_done:
#endif
-#ifdef __linux__
+#if defined(__linux__) && defined(HAVE_LIBUDEV)
struct udev *ud;
struct udev_enumerate *ud_enumerate;
struct udev_list_entry *ud_list;
#else
int result;
while (1) {
+#ifdef __ANDROID__
+ int arg = 1;
+ result = ioctl(port->fd, TCSBRK, &arg);
+#else
result = tcdrain(port->fd);
+#endif
if (result < 0) {
if (errno == EINTR) {
DEBUG("tcdrain() was interrupted");
/* Start asynchronous write. */
if (WriteFile(port->hdl, &port->pending_byte, 1, NULL, &port->write_ovl) == 0) {
if (GetLastError() == ERROR_IO_PENDING) {
- DEBUG("Asynchronous write started");
- port->writing = 1;
- RETURN_VALUE("%d", ++written);
+ if (HasOverlappedIoCompleted(&port->write_ovl)) {
+ DEBUG("Asynchronous write completed immediately");
+ port->writing = 0;
+ written++;
+ continue;
+ } else {
+ DEBUG("Asynchronous write running");
+ port->writing = 1;
+ RETURN_VALUE("%d", ++written);
+ }
} else {
/* Actual failure of some kind. */
RETURN_FAIL("WriteFile() failed");
RETURN_FAIL("ReadFile() failed");
/* Get number of bytes read. */
- GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE);
+ if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE) == 0)
+ RETURN_FAIL("GetOverlappedResult() failed");
RETURN_VALUE("%d", bytes_read);
#else