From b8e1a480388f96e6699b6af95275572b2a33abca Mon Sep 17 00:00:00 2001 From: Gareth Hancock <64541249+GazHank@users.noreply.github.com> Date: Thu, 29 Apr 2021 15:04:25 +0100 Subject: [PATCH 1/4] only set lowLatency if defined Proposed fix to address https://github.com/serialport/node-serialport/issues/2240 --- packages/bindings/src/serialport_unix.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/bindings/src/serialport_unix.cpp b/packages/bindings/src/serialport_unix.cpp index 7b8d7c7fd..07c5d8354 100644 --- a/packages/bindings/src/serialport_unix.cpp +++ b/packages/bindings/src/serialport_unix.cpp @@ -333,13 +333,15 @@ void EIO_Set(uv_work_t* req) { } #if defined(__linux__) - int err = linuxSetLowLatencyMode(data->fd, data->lowLatency); - if (err == -1) { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot get", strerror(errno)); - return; - } else if(err == -2) { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot set", strerror(errno)); - return; + if (data->lowLatency) { + int err = linuxSetLowLatencyMode(data->fd, data->lowLatency); + if (err == -1) { + snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot get", strerror(errno)); + return; + } else if(err == -2) { + snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot set", strerror(errno)); + return; + } } #endif From ca2c3d86e2baf96ca8f128b3e813e736cff5d7d2 Mon Sep 17 00:00:00 2001 From: gazhank Date: Sat, 1 May 2021 17:05:02 +0100 Subject: [PATCH 2/4] fix set and get methods for low_latency --- packages/bindings/src/serialport_linux.cpp | 21 ++++++++++- packages/bindings/src/serialport_linux.h | 1 + packages/bindings/src/serialport_unix.cpp | 43 +++++++++++----------- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/packages/bindings/src/serialport_linux.cpp b/packages/bindings/src/serialport_linux.cpp index 01fc222f9..d33baf865 100755 --- a/packages/bindings/src/serialport_linux.cpp +++ b/packages/bindings/src/serialport_linux.cpp @@ -43,6 +43,8 @@ int linuxSetLowLatencyMode(const int fd, const bool enable) { if (ioctl(fd, TIOCGSERIAL, &ss)) { return -1; } + + int oldFlags = ss.flags; if (enable) { ss.flags |= ASYNC_LOW_LATENCY; @@ -50,10 +52,25 @@ int linuxSetLowLatencyMode(const int fd, const bool enable) { ss.flags &= ~ASYNC_LOW_LATENCY; } - if (ioctl(fd, TIOCSSERIAL, &ss)) { - return -2; + if (oldFlags != ss.flags) + { + if (ioctl(fd, TIOCSSERIAL, &ss)) { + return -2; + } + } + + return 0; +} + +int linuxGetLowLatencyMode(const int fd, bool* const enabled) { + struct serial_struct ss; + + if (ioctl(fd, TIOCGSERIAL, &ss)) { + return -1; } + *enabled = ss.flags & ASYNC_LOW_LATENCY; + return 0; } diff --git a/packages/bindings/src/serialport_linux.h b/packages/bindings/src/serialport_linux.h index 2aff3bb18..f6eb928f2 100755 --- a/packages/bindings/src/serialport_linux.h +++ b/packages/bindings/src/serialport_linux.h @@ -4,6 +4,7 @@ int linuxSetCustomBaudRate(const int fd, const unsigned int baudrate); int linuxGetSystemBaudRate(const int fd, int* const outbaud); int linuxSetLowLatencyMode(const int fd, const bool enable); +int linuxGetLowLatencyMode(const int fd, bool* const enabled); #endif // PACKAGES_SERIALPORT_SRC_SERIALPORT_LINUX_H_ diff --git a/packages/bindings/src/serialport_unix.cpp b/packages/bindings/src/serialport_unix.cpp index 07c5d8354..d8cf37b30 100644 --- a/packages/bindings/src/serialport_unix.cpp +++ b/packages/bindings/src/serialport_unix.cpp @@ -332,19 +332,6 @@ void EIO_Set(uv_work_t* req) { bits |= TIOCM_DSR; } - #if defined(__linux__) - if (data->lowLatency) { - int err = linuxSetLowLatencyMode(data->fd, data->lowLatency); - if (err == -1) { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot get", strerror(errno)); - return; - } else if(err == -2) { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot set", strerror(errno)); - return; - } - } - #endif - int result = 0; if (data->brk) { result = ioctl(data->fd, TIOCSBRK, NULL); @@ -361,6 +348,17 @@ void EIO_Set(uv_work_t* req) { snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot set", strerror(errno)); return; } + + #if defined(__linux__) + int err = linuxSetLowLatencyMode(data->fd, data->lowLatency); + if (err == -1) { + snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot get", strerror(errno)); + return; + } else if(err == -2) { + snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot set", strerror(errno)); + return; +} + #endif } void EIO_Get(uv_work_t* req) { @@ -372,19 +370,20 @@ void EIO_Get(uv_work_t* req) { return; } - data->lowLatency = false; + data->cts = bits & TIOCM_CTS; + data->dsr = bits & TIOCM_DSR; + data->dcd = bits & TIOCM_CD; + #if defined(__linux__) && defined(ASYNC_LOW_LATENCY) - int latency_bits; - if (-1 == ioctl(data->fd, TIOCGSERIAL, &latency_bits)) { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot get", strerror(errno)); + bool lowlatency = false; + if (-1 == linuxGetLowLatencyMode(data->fd, &lowlatency)) { + snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot get low latency", strerror(errno)); return; } - data->lowLatency = latency_bits & ASYNC_LOW_LATENCY; + data->lowLatency = lowlatency; + #else + data->lowLatency = false; #endif - - data->cts = bits & TIOCM_CTS; - data->dsr = bits & TIOCM_DSR; - data->dcd = bits & TIOCM_CD; } void EIO_GetBaudRate(uv_work_t* req) { From 73107516e34f720e69528645016a70f3e28a40f8 Mon Sep 17 00:00:00 2001 From: gazhank Date: Sat, 1 May 2021 17:10:48 +0100 Subject: [PATCH 3/4] clarify error messages --- packages/bindings/src/serialport_unix.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bindings/src/serialport_unix.cpp b/packages/bindings/src/serialport_unix.cpp index d8cf37b30..62b42597f 100644 --- a/packages/bindings/src/serialport_unix.cpp +++ b/packages/bindings/src/serialport_unix.cpp @@ -352,10 +352,10 @@ void EIO_Set(uv_work_t* req) { #if defined(__linux__) int err = linuxSetLowLatencyMode(data->fd, data->lowLatency); if (err == -1) { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot get", strerror(errno)); + snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot get low latency", strerror(errno)); return; } else if(err == -2) { - snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot set", strerror(errno)); + snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot set low latency", strerror(errno)); return; } #endif From 1e0d14fc2c374555e7d9181aefeac400230a35de Mon Sep 17 00:00:00 2001 From: Gareth Hancock Date: Mon, 24 May 2021 21:36:07 +0100 Subject: [PATCH 4/4] Changes based on feedback --- packages/bindings/src/serialport_linux.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/bindings/src/serialport_linux.cpp b/packages/bindings/src/serialport_linux.cpp index d33baf865..7d1a60231 100755 --- a/packages/bindings/src/serialport_linux.cpp +++ b/packages/bindings/src/serialport_linux.cpp @@ -17,7 +17,7 @@ int linuxSetCustomBaudRate(const int fd, const unsigned int baudrate) { t.c_cflag |= BOTHER; t.c_ospeed = t.c_ispeed = baudrate; - if (ioctl(fd, TCSETS2, &t)) { + if (ioctl(fd, TCSETS2, &t) < 0) { return -2; } @@ -43,22 +43,19 @@ int linuxSetLowLatencyMode(const int fd, const bool enable) { if (ioctl(fd, TIOCGSERIAL, &ss)) { return -1; } - - int oldFlags = ss.flags; - if (enable) { - ss.flags |= ASYNC_LOW_LATENCY; - } else { - ss.flags &= ~ASYNC_LOW_LATENCY; - } + if (ss.flags & ASYNC_LOW_LATENCY != enable) { + + if (enable) { + ss.flags |= ASYNC_LOW_LATENCY; + } else { + ss.flags &= ~ASYNC_LOW_LATENCY; + } - if (oldFlags != ss.flags) - { - if (ioctl(fd, TIOCSSERIAL, &ss)) { + if (ioctl(fd, TIOCSSERIAL, &ss) < 0) { return -2; } } - return 0; }