Skip to content

Commit 54bd919

Browse files
committed
Attempt to fix custom baud rate issues for some Linux users
1 parent 657e501 commit 54bd919

File tree

4 files changed

+74
-175
lines changed

4 files changed

+74
-175
lines changed

src/main/c/Posix/PosixHelperFunctions.c

Lines changed: 53 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,13 @@ void cleanUpVector(serialPortVector* vector)
142142

143143
#include <linux/serial.h>
144144
#include <asm/ioctls.h>
145-
#include "termios2.h"
145+
#include <asm/termios.h>
146+
147+
#if defined (__powerpc__) || defined (__powerpc64__)
148+
#define TCSETS2 TCSETS
149+
#define TCGETS2 TCGETS
150+
#define termios2 termios
151+
#endif
146152

147153
// Common string storage functionality
148154
typedef struct stringVector
@@ -686,7 +692,7 @@ void searchForComPorts(serialPortVector* comPorts)
686692
free(line);
687693
}
688694

689-
static baud_rate getBaudRateCode(baud_rate baudRate)
695+
baud_rate getBaudRateCode(baud_rate baudRate)
690696
{
691697
// Translate a raw baud rate into a system-specified one
692698
switch (baudRate)
@@ -838,42 +844,29 @@ static baud_rate getBaudRateCode(baud_rate baudRate)
838844
default:
839845
return 0;
840846
}
841-
842-
return 0;
843847
}
844848

845-
int setConfigOptions(int portFD, baud_rate baudRate, struct termios *options)
849+
int setCustomBaudRate(int portFD, baud_rate baudRate)
846850
{
847-
// Set options using different methodologies based on availability of baud rate settings
848-
int retVal = -1;
849-
baud_rate baudRateCode = getBaudRateCode(baudRate);
850-
if (baudRateCode)
851+
// Utilize newer termios2 structure for custom baud rates
852+
struct termios2 options;
853+
int retVal = ioctl(portFD, TCGETS2, &options);
854+
if (!retVal)
851855
{
852-
// Directly set baud rate and apply all configuration options
853-
cfsetispeed(options, baudRateCode);
854-
cfsetospeed(options, baudRateCode);
855-
retVal = tcsetattr(portFD, TCSANOW, options);
856-
}
857-
else
858-
{
859-
// Copy termios info into newer termios2 data structure
860-
struct termios2 options2 = { 0 };
861-
options2.c_cflag = (options->c_cflag & ~(CBAUD | CBAUDEX)) | BOTHER;
862-
options2.c_iflag = options->c_iflag;
863-
options2.c_oflag = options->c_oflag;
864-
options2.c_lflag = options->c_lflag;
865-
options2.c_line = options->c_line;
866-
options2.c_ispeed = baudRate;
867-
options2.c_ospeed = baudRate;
868-
memcpy(options2.c_cc, options->c_cc, K_NCCS * sizeof(cc_t));
869-
retVal = ioctl(portFD, T2CSANOW, &options2);
856+
options.c_cflag &= ~CBAUD;
857+
options.c_cflag |= BOTHER;
858+
options.c_ispeed = baudRate;
859+
options.c_ospeed = baudRate;
860+
retVal = ioctl(portFD, TCSETS2, &options);
870861
}
871862
return retVal;
872863
}
873864

874865
// Solaris-specific functionality
875866
#elif defined(__sun__)
876867

868+
#include <termios.h>
869+
877870
void searchForComPorts(serialPortVector* comPorts)
878871
{
879872
// Open the Solaris callout dev directory
@@ -1054,28 +1047,14 @@ baud_rate getBaudRateCode(baud_rate baudRate)
10541047
case 460800:
10551048
return B460800;
10561049
default:
1057-
return 0;
1050+
return B38400;
10581051
}
1059-
1060-
return 0;
10611052
}
10621053

1063-
int setConfigOptions(int portFD, baud_rate baudRate, struct termios *options)
1054+
int setCustomBaudRate(int portFD, baud_rate baudRate)
10641055
{
1065-
// Set options using different methodologies based on availability of baud rate settings
1066-
baud_rate baudRateCode = getBaudRateCode(baudRate);
1067-
if (baudRateCode)
1068-
{
1069-
// Directly set baud rate and apply all configuration options
1070-
cfsetispeed(options, baudRateCode);
1071-
cfsetospeed(options, baudRateCode);
1072-
}
1073-
else
1074-
{
1075-
cfsetispeed(options, B38400);
1076-
cfsetospeed(options, B38400);
1077-
}
1078-
return tcsetattr(portFD, TCSANOW, options);
1056+
// No-op on this operating system
1057+
return 0;
10791058
}
10801059

10811060
// FreeBSD-specific functionality
@@ -1280,12 +1259,16 @@ void searchForComPorts(serialPortVector* comPorts)
12801259
}
12811260
}
12821261

1283-
int setConfigOptions(int portFD, baud_rate baudRate, struct termios *options)
1262+
baud_rate getBaudRateCode(baud_rate baudRate)
12841263
{
1285-
// Directly set baud rate and apply all configuration options
1286-
cfsetispeed(options, baudRate);
1287-
cfsetospeed(options, baudRate);
1288-
return tcsetattr(portFD, TCSANOW, options);
1264+
// Baud rates are set directly with no explicit codes
1265+
return baudRate;
1266+
}
1267+
1268+
int setCustomBaudRate(int portFD, baud_rate baudRate)
1269+
{
1270+
// No-op on this operating system
1271+
return 0;
12891272
}
12901273

12911274
// OpenBSD-specific functionality
@@ -1470,12 +1453,16 @@ void searchForComPorts(serialPortVector* comPorts)
14701453
}
14711454
}
14721455

1473-
int setConfigOptions(int portFD, baud_rate baudRate, struct termios *options)
1456+
baud_rate getBaudRateCode(baud_rate baudRate)
14741457
{
1475-
// Directly set baud rate and apply all configuration options
1476-
cfsetispeed(options, baudRate);
1477-
cfsetospeed(options, baudRate);
1478-
return tcsetattr(portFD, TCSANOW, options);
1458+
// Baud rates are set directly with no explicit codes
1459+
return baudRate;
1460+
}
1461+
1462+
int setCustomBaudRate(int portFD, baud_rate baudRate)
1463+
{
1464+
// No-op on this operating system
1465+
return 0;
14791466
}
14801467

14811468
// Apple-specific functionality
@@ -1487,6 +1474,7 @@ int setConfigOptions(int portFD, baud_rate baudRate, struct termios *options)
14871474
#include <IOKit/serial/IOSerialKeys.h>
14881475
#include <IOKit/serial/ioss.h>
14891476
#include <sys/ioctl.h>
1477+
#include <termios.h>
14901478

14911479
void searchForComPorts(serialPortVector* comPorts)
14921480
{
@@ -1720,28 +1708,17 @@ baud_rate getBaudRateCode(baud_rate baudRate)
17201708
return 0;
17211709
}
17221710

1723-
int setConfigOptions(int portFD, baud_rate baudRate, struct termios *options)
1711+
int setCustomBaudRate(int portFD, baud_rate baudRate)
17241712
{
1725-
// Set options using different methodologies based on availability of baud rate settings
1726-
int retVal = -1;
1727-
baud_rate baudRateCode = getBaudRateCode(baudRate);
1728-
if (baudRateCode)
1729-
{
1730-
// Directly set baud rate and apply all configuration options
1731-
cfsetispeed(options, baudRateCode);
1732-
cfsetospeed(options, baudRateCode);
1733-
retVal = tcsetattr(portFD, TCSANOW, options);
1734-
}
1735-
else
1736-
{
1737-
// Use OSX-specific ioctls to set a custom baud rate
1738-
cfsetispeed(options, B9600);
1739-
cfsetospeed(options, B9600);
1740-
unsigned long microseconds = 1000;
1741-
retVal = tcsetattr(portFD, TCSANOW, options) & ioctl(portFD, IOSSIOSPEED, &baudRate);
1742-
if (retVal == 0)
1743-
retVal = ioctl(portFD, IOSSDATALAT, &microseconds);
1744-
}
1713+
// Use OSX-specific ioctls to set a custom baud rate
1714+
struct termios options;
1715+
tcgetattr(portFD, &options);
1716+
cfsetispeed(&options, B9600);
1717+
cfsetospeed(&options, B9600);
1718+
unsigned long microseconds = 1000;
1719+
int retVal = tcsetattr(portFD, TCSANOW, &options) & ioctl(portFD, IOSSIOSPEED, &baudRate);
1720+
if (retVal == 0)
1721+
retVal = ioctl(portFD, IOSSDATALAT, &microseconds);
17451722
return retVal;
17461723
}
17471724

src/main/c/Posix/PosixHelperFunctions.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
* PosixHelperFunctions.h
33
*
44
* Created on: Mar 10, 2015
5-
* Last Updated on: Apr 10, 2024
5+
* Last Updated on: Oct 31, 2025
66
* Author: Will Hedgecock
77
*
8-
* Copyright (C) 2012-2024 Fazecast, Inc.
8+
* Copyright (C) 2012-2025 Fazecast, Inc.
99
*
1010
* This file is part of jSerialComm.
1111
*
@@ -28,7 +28,6 @@
2828

2929
// Serial port JNI header file
3030
#include <pthread.h>
31-
#include <termios.h>
3231
#include "com_fazecast_jSerialComm_SerialPort.h"
3332

3433
// Serial port data structure
@@ -97,6 +96,8 @@ typedef int baud_rate;
9796
// Apple-specific functionality
9897
#elif defined(__APPLE__)
9998

99+
#include <termios.h>
100+
100101
#define fdatasync fsync
101102

102103
typedef speed_t baud_rate;
@@ -106,7 +107,8 @@ typedef speed_t baud_rate;
106107

107108
// Common Posix functionality
108109
void searchForComPorts(serialPortVector* comPorts);
109-
int setConfigOptions(int portFD, baud_rate baudRate, struct termios *options);
110110
int verifyAndSetUserPortGroup(const char *portFile);
111+
baud_rate getBaudRateCode(baud_rate baudRate);
112+
int setCustomBaudRate(int portFD, baud_rate baudRate);
111113

112114
#endif // #ifndef __POSIX_HELPER_FUNCTIONS_HEADER_H__

src/main/c/Posix/SerialPort_Posix.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <sys/file.h>
3434
#include <sys/ioctl.h>
3535
#include <sys/time.h>
36+
#include <termios.h>
3637
#include <time.h>
3738
#include <unistd.h>
3839
#if defined(__linux__)
@@ -767,7 +768,20 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
767768
port->errorNumber = lastErrorNumber = errno;
768769
return JNI_FALSE;
769770
}
770-
if (setConfigOptions(port->handle, baudRate, &options))
771+
baud_rate baudRateCode = getBaudRateCode(baudRate);
772+
if (baudRateCode)
773+
{
774+
cfsetispeed(&options, baudRateCode);
775+
cfsetospeed(&options, baudRateCode);
776+
}
777+
if (tcsetattr(port->handle, TCSANOW, &options))
778+
{
779+
port->errorLineNumber = lastErrorLineNumber = __LINE__ - 2;
780+
port->errorNumber = lastErrorNumber = errno;
781+
if (!disableConfig)
782+
return JNI_FALSE;
783+
}
784+
if (!baudRateCode && setCustomBaudRate(port->handle, baudRate))
771785
{
772786
port->errorLineNumber = lastErrorLineNumber = __LINE__ - 2;
773787
port->errorNumber = lastErrorNumber = errno;

src/main/c/Posix/termios2.h

Lines changed: 0 additions & 94 deletions
This file was deleted.

0 commit comments

Comments
 (0)