From da7669f3dc665cb1da26c8c46c5d677ba9c112c6 Mon Sep 17 00:00:00 2001 From: stefanrueger Date: Tue, 13 May 2025 00:18:14 +0200 Subject: [PATCH 1/2] Fix r/w timeout for Windows ser_send() --- src/ser_win32.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/ser_win32.c b/src/ser_win32.c index 8a53ad46..d3f7f414 100644 --- a/src/ser_win32.c +++ b/src/ser_win32.c @@ -81,6 +81,15 @@ static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) { // ms return SetCommTimeouts(hComPort, &ctmo); } +static BOOL serial_w32SetRWTimeOut(HANDLE hComPort, DWORD timeout) { // ms + COMMTIMEOUTS ctmo = {0}; + + ctmo.ReadTotalTimeoutConstant = timeout; + ctmo.WriteTotalTimeoutConstant = timeout; + + return SetCommTimeouts(hComPort, &ctmo); +} + static int ser_setparams(const union filedescriptor *fd, long baud, unsigned long cflags) { if(cx->ser_serial_over_ethernet) return -ENOTTY; @@ -343,7 +352,10 @@ static int ser_send(const union filedescriptor *fd, const unsigned char *buf, si if(verbose >= MSG_TRACE) trace_buffer(__func__, buf, len); - serial_w32SetTimeOut(hComPort, 500); + if(!serial_w32SetRWTimeOut(hComPort, (len > 5? len: 5)*100)) { + pmsg_error("cannot set r/w timeout for serial port\n"); + return -1; + } if(!WriteFile(hComPort, buf, len, &written, NULL)) { pmsg_error("unable to write: %s\n", "sorry no info avail"); // TODO From e9d58b5f30000cc31fa72765778796691e784bca Mon Sep 17 00:00:00 2001 From: stefanrueger Date: Tue, 13 May 2025 13:16:47 +0200 Subject: [PATCH 2/2] Increase windows serial timeouts for 110 baud or more --- src/ser_win32.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/ser_win32.c b/src/ser_win32.c index d3f7f414..b9333d48 100644 --- a/src/ser_win32.c +++ b/src/ser_win32.c @@ -70,7 +70,8 @@ static DWORD serial_baud_lookup(long baud) { return baud; } -static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) { // ms +// Set read timeout in ms +static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) { COMMTIMEOUTS ctmo; ZeroMemory(&ctmo, sizeof(COMMTIMEOUTS)); @@ -81,7 +82,8 @@ static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) { // ms return SetCommTimeouts(hComPort, &ctmo); } -static BOOL serial_w32SetRWTimeOut(HANDLE hComPort, DWORD timeout) { // ms +// Set read/write timeout in ms +static BOOL serial_w32SetRWTimeOut(HANDLE hComPort, DWORD timeout) { COMMTIMEOUTS ctmo = {0}; ctmo.ReadTotalTimeoutConstant = timeout; @@ -352,7 +354,8 @@ static int ser_send(const union filedescriptor *fd, const unsigned char *buf, si if(verbose >= MSG_TRACE) trace_buffer(__func__, buf, len); - if(!serial_w32SetRWTimeOut(hComPort, (len > 5? len: 5)*100)) { + // Set minimum r/w timeout to 2000 ms or higher to cater for 110 baud or faster + if(!serial_w32SetRWTimeOut(hComPort, (len > 20? len: 20)*100)) { pmsg_error("cannot set r/w timeout for serial port\n"); return -1; } @@ -445,7 +448,12 @@ static int ser_recv(const union filedescriptor *fd, unsigned char *buf, size_t b return -1; } - serial_w32SetTimeOut(hComPort, serial_recv_timeout); + // Ensure can receive buflen bytes at 8N1 at 110 baud or higher: one byte takes 91 ms at 110 baud + long timeout = (long) buflen*100 > serial_recv_timeout? (long) buflen*100: serial_recv_timeout; + if(!serial_w32SetTimeOut(hComPort, timeout)) { + pmsg_error("cannot set read timeout for serial port\n"); + return -1; + } if(!ReadFile(hComPort, buf, buflen, &read, NULL)) { LPVOID lpMsgBuf; @@ -553,9 +561,8 @@ static int ser_drain(const union filedescriptor *fd, int display) { serial_w32SetTimeOut(hComPort, serial_drain_timeout); - if(display) { + if(display) msg_info("drain>"); - } while(1) { readres = ReadFile(hComPort, buf, 1, &read, NULL);