+ if (!(data->term.c_cflag & PARENB) && (data->term.c_iflag & IGNPAR))
+ config->parity = SP_PARITY_NONE;
+ else if (!(data->term.c_cflag & PARENB) || (data->term.c_iflag & IGNPAR))
+ config->parity = -1;
+ else
+ config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_ODD : SP_PARITY_EVEN;
+
+ config->stopbits = (data->term.c_cflag & CSTOPB) ? 2 : 1;
+
+ if (data->term.c_cflag & CRTSCTS) {
+ config->rts = SP_RTS_FLOW_CONTROL;
+ config->cts = SP_CTS_FLOW_CONTROL;
+ } else {
+#ifdef USE_TERMIOX
+ if (data->flow & RTS_FLOW)
+ config->rts = SP_RTS_FLOW_CONTROL;
+ else
+ config->rts = (data->controlbits & TIOCM_RTS) ? SP_RTS_ON : SP_RTS_OFF;
+
+ config->cts = (data->flow & CTS_FLOW) ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
+#else
+ config->rts = (data->controlbits & TIOCM_RTS) ? SP_RTS_ON : SP_RTS_OFF;
+ config->cts = SP_CTS_IGNORE;
+#endif
+ }
+
+#ifdef USE_TERMIOX
+ if (data->flow & DTR_FLOW)
+ config->dtr = SP_DTR_FLOW_CONTROL;
+ else
+ config->dtr = (data->controlbits & TIOCM_DTR) ? SP_DTR_ON : SP_DTR_OFF;
+
+ config->dsr = (data->flow & DSR_FLOW) ? SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
+#else
+ config->dtr = (data->controlbits & TIOCM_DTR) ? SP_DTR_ON : SP_DTR_OFF;
+ config->dsr = SP_DSR_IGNORE;
+#endif
+
+ if (data->term.c_iflag & IXOFF) {
+ if (data->term.c_iflag & IXON)
+ config->xon_xoff = SP_XONXOFF_INOUT;
+ else
+ config->xon_xoff = SP_XONXOFF_IN;
+ } else {
+ if (data->term.c_iflag & IXON)
+ config->xon_xoff = SP_XONXOFF_OUT;
+ else
+ config->xon_xoff = SP_XONXOFF_DISABLED;
+ }
+#endif
+
+ return SP_OK;
+}
+
+static enum sp_return set_config(struct sp_port *port, struct port_data *data,
+ const struct sp_port_config *config)
+{
+ unsigned int i;
+#ifdef __APPLE__
+ BAUD_TYPE baud_nonstd;
+
+ baud_nonstd = B0;
+#endif
+#ifdef __linux__
+ int baud_nonstd = 0;
+#endif
+
+#ifdef _WIN32
+ if (config->baudrate >= 0) {
+ for (i = 0; i < NUM_STD_BAUDRATES; i++) {
+ if (config->baudrate == std_baudrates[i].value) {
+ data->dcb.BaudRate = std_baudrates[i].index;
+ break;
+ }
+ }
+
+ if (i == NUM_STD_BAUDRATES)
+ data->dcb.BaudRate = config->baudrate;
+ }
+
+ if (config->bits >= 0)
+ data->dcb.ByteSize = config->bits;
+
+ if (config->parity >= 0) {
+ switch (config->parity) {
+ /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
+ case SP_PARITY_NONE:
+ data->dcb.Parity = NOPARITY;
+ break;
+ case SP_PARITY_EVEN:
+ data->dcb.Parity = EVENPARITY;
+ break;
+ case SP_PARITY_ODD:
+ data->dcb.Parity = ODDPARITY;
+ break;
+ default:
+ return SP_ERR_ARG;
+ }
+ }
+
+ if (config->stopbits >= 0) {
+ switch (config->stopbits) {
+ /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
+ case 1:
+ data->dcb.StopBits = ONESTOPBIT;
+ break;
+ case 2:
+ data->dcb.StopBits = TWOSTOPBITS;
+ break;
+ default:
+ return SP_ERR_ARG;
+ }
+ }
+
+ if (config->rts >= 0) {
+ switch (config->rts) {
+ case SP_RTS_OFF:
+ data->dcb.fRtsControl = RTS_CONTROL_DISABLE;
+ break;
+ case SP_RTS_ON:
+ data->dcb.fRtsControl = RTS_CONTROL_ENABLE;
+ break;
+ case SP_RTS_FLOW_CONTROL:
+ data->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
+ break;
+ default:
+ return SP_ERR_ARG;
+ }
+ }
+
+ if (config->cts >= 0) {
+ switch (config->cts) {
+ case SP_CTS_IGNORE:
+ data->dcb.fOutxCtsFlow = FALSE;
+ break;
+ case SP_CTS_FLOW_CONTROL:
+ data->dcb.fOutxCtsFlow = TRUE;
+ break;
+ default:
+ return SP_ERR_ARG;
+ }
+ }