mirror of
https://github.com/UzixLS/picocom.git
synced 2025-07-19 07:21:18 +03:00
Better flowcntrl parsing/setting for RFC2217 ports
Use the same code to parse the flow-control setting from a termios structure and to write the flow-control settings to a termios structure for both: native and RFC2217 ports.
This commit is contained in:
109
term.c
109
term.c
@ -1234,82 +1234,75 @@ term_get_stopbits (int fd)
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int
|
||||
tios_set_flowcntrl(struct termios *tios, enum flowcntrl_e flowcntl)
|
||||
{
|
||||
int rval = 0;
|
||||
|
||||
switch (flowcntl) {
|
||||
case FC_RTSCTS:
|
||||
tios->c_cflag |= CRTSCTS;
|
||||
tios->c_iflag &= ~(IXON | IXOFF | IXANY);
|
||||
break;
|
||||
case FC_XONXOFF:
|
||||
tios->c_cflag &= ~(CRTSCTS);
|
||||
tios->c_iflag |= IXON | IXOFF;
|
||||
break;
|
||||
case FC_NONE:
|
||||
tios->c_cflag &= ~(CRTSCTS);
|
||||
tios->c_iflag &= ~(IXON | IXOFF | IXANY);
|
||||
break;
|
||||
default:
|
||||
term_errno = TERM_EFLOW;
|
||||
rval = -1;
|
||||
break;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
term_set_flowcntrl (int fd, enum flowcntrl_e flowcntl)
|
||||
{
|
||||
int rval;
|
||||
struct term_s *t;
|
||||
struct termios *tiop;
|
||||
|
||||
rval = 0;
|
||||
t = term_find(fd);
|
||||
if ( ! t ) return -1;
|
||||
|
||||
do { /* dummy */
|
||||
return tios_set_flowcntrl(&t->nexttermios, flowcntl);
|
||||
}
|
||||
|
||||
t = term_find(fd);
|
||||
if ( ! t ) {
|
||||
rval = -1;
|
||||
break;
|
||||
}
|
||||
enum flowcntrl_e
|
||||
tios_get_flowcntrl(const struct termios *tios)
|
||||
{
|
||||
enum flowcntrl_e flow;
|
||||
int rtscts, xoff, xon;
|
||||
|
||||
tiop = &t->nexttermios;
|
||||
rtscts = (tios->c_cflag & CRTSCTS) ? 1 : 0;
|
||||
xoff = (tios->c_iflag & IXOFF) ? 1 : 0;
|
||||
xon = (tios->c_iflag & (IXON | IXANY)) ? 1 : 0;
|
||||
|
||||
switch (flowcntl) {
|
||||
case FC_RTSCTS:
|
||||
tiop->c_cflag |= CRTSCTS;
|
||||
tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
|
||||
break;
|
||||
case FC_XONXOFF:
|
||||
tiop->c_cflag &= ~(CRTSCTS);
|
||||
tiop->c_iflag |= IXON | IXOFF;
|
||||
break;
|
||||
case FC_NONE:
|
||||
tiop->c_cflag &= ~(CRTSCTS);
|
||||
tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
|
||||
break;
|
||||
default:
|
||||
term_errno = TERM_EFLOW;
|
||||
rval = -1;
|
||||
break;
|
||||
}
|
||||
if ( rval < 0 ) break;
|
||||
if ( rtscts && ! xoff && ! xon ) {
|
||||
flow = FC_RTSCTS;
|
||||
} else if ( ! rtscts && xoff && xon ) {
|
||||
flow = FC_XONXOFF;
|
||||
} else if ( ! rtscts && ! xoff && ! xon ) {
|
||||
flow = FC_NONE;
|
||||
} else {
|
||||
flow = FC_OTHER;
|
||||
}
|
||||
|
||||
} while (0);
|
||||
|
||||
return rval;
|
||||
return flow;
|
||||
}
|
||||
|
||||
enum flowcntrl_e
|
||||
term_get_flowcntrl (int fd)
|
||||
{
|
||||
struct term_s *t;
|
||||
enum flowcntrl_e flow;
|
||||
int rtscts, xoff, xon;
|
||||
|
||||
do { /* dummy */
|
||||
t = term_find(fd);
|
||||
if ( ! t ) return FC_ERROR;
|
||||
|
||||
t = term_find(fd);
|
||||
if ( ! t ) {
|
||||
flow = FC_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
rtscts = (t->currtermios.c_cflag & CRTSCTS) ? 1 : 0;
|
||||
xoff = (t->currtermios.c_iflag & IXOFF) ? 1 : 0;
|
||||
xon = (t->currtermios.c_iflag & (IXON | IXANY)) ? 1 : 0;
|
||||
|
||||
if ( rtscts && ! xoff && ! xon ) {
|
||||
flow = FC_RTSCTS;
|
||||
} else if ( ! rtscts && xoff && xon ) {
|
||||
flow = FC_XONXOFF;
|
||||
} else if ( ! rtscts && ! xoff && ! xon ) {
|
||||
flow = FC_NONE;
|
||||
} else {
|
||||
flow = FC_OTHER;
|
||||
}
|
||||
|
||||
} while (0);
|
||||
|
||||
return flow;
|
||||
return tios_get_flowcntrl(&t->currtermios);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define TERMINT_H
|
||||
|
||||
#include <termios.h>
|
||||
#include "term.h"
|
||||
|
||||
struct term_s {
|
||||
/* Read-only fields */
|
||||
@ -55,6 +56,9 @@ struct term_ops {
|
||||
int (*write)(struct term_s *t, const void *buf, unsigned bufsz);
|
||||
};
|
||||
|
||||
enum flowcntrl_e tios_get_flowcntrl(const struct termios *tios);
|
||||
int tios_set_flowcntrl(struct termios *tios, enum flowcntrl_e flowcntl);
|
||||
|
||||
#endif /* of TERMINT_H */
|
||||
|
||||
/***************************************************************************/
|
||||
|
36
tn2217.c
36
tn2217.c
@ -586,14 +586,25 @@ tn2217_send_set_stopsize(struct term_s *t, int c_flag)
|
||||
|
||||
/* Sends a SET-CONTROL message to control hardware flow control */
|
||||
static void
|
||||
tn2217_send_set_fc(struct term_s *t, int c_flag)
|
||||
tn2217_send_set_fc(struct term_s *t, enum flowcntrl_e flow)
|
||||
{
|
||||
unsigned char val;
|
||||
|
||||
if (c_flag & CRTSCTS)
|
||||
switch (flow) {
|
||||
case FC_RTSCTS:
|
||||
val = COMPORT_CONTROL_FC_HARDWARE;
|
||||
else
|
||||
fprintf(stderr,"--> FC_HARDWARE\r\n");
|
||||
break;
|
||||
case FC_XONXOFF:
|
||||
val = COMPORT_CONTROL_FC_XONOFF;
|
||||
fprintf(stderr,"--> FC_XONXOFF\r\n");
|
||||
break;
|
||||
case FC_NONE:
|
||||
default:
|
||||
val = COMPORT_CONTROL_FC_NONE;
|
||||
fprintf(stderr,"--> FC_NONE\r\n");
|
||||
break;
|
||||
}
|
||||
tn2217_send_comport_cmd1(t, COMPORT_SET_CONTROL, val);
|
||||
}
|
||||
|
||||
@ -644,7 +655,7 @@ tn2217_comport_start(struct term_s *t)
|
||||
tn2217_send_set_datasize(t, s->termios.c_cflag);
|
||||
tn2217_send_set_parity(t, s->termios.c_cflag);
|
||||
tn2217_send_set_stopsize(t, s->termios.c_cflag);
|
||||
tn2217_send_set_fc(t, s->termios.c_cflag);
|
||||
tn2217_send_set_fc(t, tios_get_flowcntrl(&s->termios));
|
||||
} else {
|
||||
/* If we're not going to specify it, ask for
|
||||
* the current com port geometry. */
|
||||
@ -782,14 +793,19 @@ tn2217_recv_comport_cmd(struct term_s *t, unsigned char cmd,
|
||||
if (datalen >= 1) {
|
||||
switch (data[0]) {
|
||||
/* Flow control changes and COMPORT_CONTROL_FC_REQUEST reply */
|
||||
case COMPORT_CONTROL_FC_NONE:
|
||||
case COMPORT_CONTROL_FC_XONOFF:
|
||||
fprintf(stderr, "[notified FC_XONXOFF]\r\n");
|
||||
tios_set_flowcntrl(tio, FC_XONXOFF);
|
||||
break;
|
||||
case COMPORT_CONTROL_FC_HARDWARE:
|
||||
fprintf(stderr, "[notified FC_RTSCTS]\r\n");
|
||||
tios_set_flowcntrl(tio, FC_RTSCTS);
|
||||
break;
|
||||
case COMPORT_CONTROL_FC_NONE:
|
||||
case COMPORT_CONTROL_FC_DCD:
|
||||
case COMPORT_CONTROL_FC_DSR:
|
||||
case COMPORT_CONTROL_FC_HARDWARE:
|
||||
val = (data[0] == COMPORT_CONTROL_FC_HARDWARE ) ? CRTSCTS : 0;
|
||||
tio->c_cflag &= ~CRTSCTS;
|
||||
tio->c_cflag |= val;
|
||||
fprintf(stderr, "[notified FC_NONE]\r\n");
|
||||
tios_set_flowcntrl(tio, FC_NONE);
|
||||
break;
|
||||
/* DTR changes and COMPORT_CONTROL_DTR_REQUEST reply */
|
||||
case COMPORT_CONTROL_DTR_ON:
|
||||
@ -889,7 +905,7 @@ tn2217_tcsetattr(struct term_s *t, int when, const struct termios *tio)
|
||||
tn2217_send_set_datasize(t, tio->c_cflag);
|
||||
tn2217_send_set_parity(t, tio->c_cflag);
|
||||
tn2217_send_set_stopsize(t, tio->c_cflag);
|
||||
tn2217_send_set_fc(t, tio->c_cflag);
|
||||
tn2217_send_set_fc(t, tios_get_flowcntrl(tio));
|
||||
} else
|
||||
s->set_termios = 1;
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user