Skip to content

Commit

Permalink
Merge pull request #1 from GazHank/pr/GazHank/2241-1
Browse files Browse the repository at this point in the history
Fix for linux low latency mode issue serialport#2240 (revised)
  • Loading branch information
GazHank authored May 1, 2021
2 parents b8e1a48 + 7310751 commit 60a167b
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 24 deletions.
21 changes: 19 additions & 2 deletions packages/bindings/src/serialport_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,34 @@ 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 (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;
}

Expand Down
1 change: 1 addition & 0 deletions packages/bindings/src/serialport_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_

43 changes: 21 additions & 22 deletions packages/bindings/src/serialport_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 low latency", strerror(errno));
return;
} else if(err == -2) {
snprintf(data->errorString, sizeof(data->errorString), "Error: %s, cannot set low latency", strerror(errno));
return;
}
#endif
}

void EIO_Get(uv_work_t* req) {
Expand All @@ -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) {
Expand Down

0 comments on commit 60a167b

Please sign in to comment.