diff --git a/third_party/libserialport/libserialport.h b/third_party/libserialport/libserialport.h index 7467f74..3bbae37 100644 --- a/third_party/libserialport/libserialport.h +++ b/third_party/libserialport/libserialport.h @@ -450,7 +450,9 @@ enum sp_transport { /** USB serial port adapter. @since 0.1.1 */ SP_TRANSPORT_USB, /** Bluetooth serial port adapter. @since 0.1.1 */ - SP_TRANSPORT_BLUETOOTH + SP_TRANSPORT_BLUETOOTH, + /** Pseudo serial port. @since 0.1.2 */ + SP_TRANSPORT_PSEUDO }; /** diff --git a/third_party/libserialport/linux.c b/third_party/libserialport/linux.c index 8f32085..feee9ec 100644 --- a/third_party/libserialport/linux.c +++ b/third_party/libserialport/linux.c @@ -56,18 +56,22 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port) RETURN_ERROR(SP_ERR_ARG, "Device name not recognized"); snprintf(link_name, sizeof(link_name), "/sys/class/tty/%s", dev); - if (lstat(link_name, &statbuf) == -1) - RETURN_ERROR(SP_ERR_ARG, "Device not found"); - if (!S_ISLNK(statbuf.st_mode)) - snprintf(link_name, sizeof(link_name), "/sys/class/tty/%s/device", dev); - count = readlink(link_name, file_name, sizeof(file_name)); - if (count <= 0 || count >= (int)(sizeof(file_name) - 1)) - RETURN_ERROR(SP_ERR_ARG, "Device not found"); - file_name[count] = 0; - if (strstr(file_name, "bluetooth")) - port->transport = SP_TRANSPORT_BLUETOOTH; - else if (strstr(file_name, "usb")) - port->transport = SP_TRANSPORT_USB; + if (lstat(link_name, &statbuf) == -1) { + if (strncmp(port->name + 5, "pts/", 4)) + RETURN_ERROR(SP_ERR_ARG, "Device not found"); + port->transport = SP_TRANSPORT_PSEUDO; + } else { + if (!S_ISLNK(statbuf.st_mode)) + snprintf(link_name, sizeof(link_name), "/sys/class/tty/%s/device", dev); + count = readlink(link_name, file_name, sizeof(file_name)); + if (count <= 0 || count >= (int)(sizeof(file_name) - 1)) + RETURN_ERROR(SP_ERR_ARG, "Device not found"); + file_name[count] = 0; + if (strstr(file_name, "bluetooth")) + port->transport = SP_TRANSPORT_BLUETOOTH; + else if (strstr(file_name, "usb")) + port->transport = SP_TRANSPORT_USB; + } if (port->transport == SP_TRANSPORT_USB) { for (i = 0; i < 5; i++) { diff --git a/third_party/libserialport/serialport.c b/third_party/libserialport/serialport.c index 1daba1c..7327aad 100644 --- a/third_party/libserialport/serialport.c +++ b/third_party/libserialport/serialport.c @@ -47,6 +47,8 @@ static const struct std_baudrate std_baudrates[] = { void (*sp_debug_handler)(const char *format, ...) = sp_default_debug_handler; +static void init_config(struct sp_port_config *config); + static enum sp_return get_config(struct sp_port *port, struct port_data *data, struct sp_port_config *config); @@ -1652,6 +1654,18 @@ static enum sp_return set_flow(int fd, struct port_data *data) } #endif /* USE_TERMIOX */ +static void init_config(struct sp_port_config *config) +{ + config->baudrate = -1; + config->bits = -1; + config->parity = -1; + config->stopbits = -1; + config->rts = -1; + config->cts = -1; + config->dtr = -1; + config->dsr = -1; +} + static enum sp_return get_config(struct sp_port *port, struct port_data *data, struct sp_port_config *config) { @@ -1661,6 +1675,8 @@ static enum sp_return get_config(struct sp_port *port, struct port_data *data, DEBUG_FMT("Getting configuration for port %s", port->name); + init_config(config); + #ifdef _WIN32 if (!GetCommState(port->hdl, &data->dcb)) RETURN_FAIL("GetCommState() failed"); @@ -1758,7 +1774,8 @@ static enum sp_return get_config(struct sp_port *port, struct port_data *data, if (tcgetattr(port->fd, &data->term) < 0) RETURN_FAIL("tcgetattr() failed"); - if (ioctl(port->fd, TIOCMGET, &data->controlbits) < 0) +if (port->transport != SP_TRANSPORT_PSEUDO && ioctl(port->fd, TIOCMGET, + &data->controlbits) < 0) RETURN_FAIL("TIOCMGET ioctl failed"); #ifdef USE_TERMIOX @@ -1824,7 +1841,7 @@ static enum sp_return get_config(struct sp_port *port, struct port_data *data, if (data->term.c_cflag & CRTSCTS) { config->rts = SP_RTS_FLOW_CONTROL; config->cts = SP_CTS_FLOW_CONTROL; - } else { + } else if (port->transport != SP_TRANSPORT_PSEUDO) { if (data->termiox_supported && data->rts_flow) config->rts = SP_RTS_FLOW_CONTROL; else @@ -1836,11 +1853,12 @@ static enum sp_return get_config(struct sp_port *port, struct port_data *data, if (data->termiox_supported && data->dtr_flow) config->dtr = SP_DTR_FLOW_CONTROL; - else + else if (port->transport != SP_TRANSPORT_PSEUDO) config->dtr = (data->controlbits & TIOCM_DTR) ? SP_DTR_ON : SP_DTR_OFF; - config->dsr = (data->termiox_supported && data->dsr_flow) ? - SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE; + if (port->transport != SP_TRANSPORT_PSEUDO) + config->dsr = (data->termiox_supported && data->dsr_flow) ? + SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE; if (data->term.c_iflag & IXOFF) { if (data->term.c_iflag & IXON) @@ -2272,14 +2290,16 @@ SP_API enum sp_return sp_new_config(struct sp_port_config **config_ptr) if (!(config = malloc(sizeof(struct sp_port_config)))) RETURN_ERROR(SP_ERR_MEM, "Config malloc failed"); - config->baudrate = -1; - config->bits = -1; - config->parity = -1; - config->stopbits = -1; - config->rts = -1; - config->cts = -1; - config->dtr = -1; - config->dsr = -1; + // config->baudrate = -1; + // config->bits = -1; + // config->parity = -1; + // config->stopbits = -1; + // config->rts = -1; + // config->cts = -1; + // config->dtr = -1; + // config->dsr = -1; + + init_config(config); *config_ptr = config;