core: update some serial port settings
1) use cfsetispeed/cfsetospeed like the TTY manpage suggests 2) ignore parity/framing errors since we're not using parity anyway 3) double-check that all our TTY settings were successfully set
This commit is contained in:
@@ -324,7 +324,7 @@ static gboolean
|
|||||||
real_config_fd (MMSerialPort *self, int fd, GError **error)
|
real_config_fd (MMSerialPort *self, int fd, GError **error)
|
||||||
{
|
{
|
||||||
MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
|
MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
|
||||||
struct termios stbuf;
|
struct termios stbuf, other;
|
||||||
int speed;
|
int speed;
|
||||||
int bits;
|
int bits;
|
||||||
int parity;
|
int parity;
|
||||||
@@ -343,7 +343,7 @@ real_config_fd (MMSerialPort *self, int fd, GError **error)
|
|||||||
errno);
|
errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
stbuf.c_iflag &= ~(IGNCR | ICRNL | IUCLC | INPCK | IXON | IXANY | IGNPAR );
|
stbuf.c_iflag &= ~(IGNCR | ICRNL | IUCLC | INPCK | IXON | IXANY );
|
||||||
stbuf.c_oflag &= ~(OPOST | OLCUC | OCRNL | ONLCR | ONLRET);
|
stbuf.c_oflag &= ~(OPOST | OLCUC | OCRNL | ONLCR | ONLRET);
|
||||||
stbuf.c_lflag &= ~(ICANON | XCASE | ECHO | ECHOE | ECHONL);
|
stbuf.c_lflag &= ~(ICANON | XCASE | ECHO | ECHOE | ECHONL);
|
||||||
stbuf.c_lflag &= ~(ECHO | ECHOE);
|
stbuf.c_lflag &= ~(ECHO | ECHOE);
|
||||||
@@ -351,14 +351,34 @@ real_config_fd (MMSerialPort *self, int fd, GError **error)
|
|||||||
stbuf.c_cc[VTIME] = 0;
|
stbuf.c_cc[VTIME] = 0;
|
||||||
stbuf.c_cc[VEOF] = 1;
|
stbuf.c_cc[VEOF] = 1;
|
||||||
|
|
||||||
/* Use software handshaking */
|
/* Use software handshaking and ignore parity/framing errors */
|
||||||
stbuf.c_iflag |= (IXON | IXOFF | IXANY);
|
stbuf.c_iflag |= (IXON | IXOFF | IXANY | IGNPAR);
|
||||||
|
|
||||||
/* Set up port speed and serial attributes; also ignore modem control
|
/* Set up port speed and serial attributes; also ignore modem control
|
||||||
* lines since most drivers don't implement RTS/CTS anyway.
|
* lines since most drivers don't implement RTS/CTS anyway.
|
||||||
*/
|
*/
|
||||||
stbuf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | PARENB | CRTSCTS);
|
stbuf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | PARENB | CRTSCTS);
|
||||||
stbuf.c_cflag |= (speed | bits | CREAD | 0 | parity | stopbits | CLOCAL);
|
stbuf.c_cflag |= (bits | CREAD | 0 | parity | stopbits | CLOCAL);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (cfsetispeed (&stbuf, speed) != 0) {
|
||||||
|
g_set_error (error,
|
||||||
|
MM_MODEM_ERROR,
|
||||||
|
MM_MODEM_ERROR_GENERAL,
|
||||||
|
"%s: failed to set serial port input speed; errno %d",
|
||||||
|
__func__, errno);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (cfsetospeed (&stbuf, speed) != 0) {
|
||||||
|
g_set_error (error,
|
||||||
|
MM_MODEM_ERROR,
|
||||||
|
MM_MODEM_ERROR_GENERAL,
|
||||||
|
"%s: failed to set serial port output speed; errno %d",
|
||||||
|
__func__, errno);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (tcsetattr (fd, TCSANOW, &stbuf) < 0) {
|
if (tcsetattr (fd, TCSANOW, &stbuf) < 0) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
@@ -369,6 +389,22 @@ real_config_fd (MMSerialPort *self, int fd, GError **error)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* tcsetattr() returns 0 if any of the requested attributes could be set,
|
||||||
|
* so we should double-check that all were set and log a warning if not.
|
||||||
|
*/
|
||||||
|
memset (&other, 0, sizeof (struct termios));
|
||||||
|
errno = 0;
|
||||||
|
if (tcgetattr (fd, &other) != 0) {
|
||||||
|
mm_warn ("(%s): tcgetattr() error: %d",
|
||||||
|
mm_port_get_device (MM_PORT (self)),
|
||||||
|
errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp (&stbuf, &other, sizeof (other)) != 0) {
|
||||||
|
mm_warn ("(%s): port attributes not fully set",
|
||||||
|
mm_port_get_device (MM_PORT (self)));
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user