improved handling of modem/line status

This commit is contained in:
Frank Rolsted Jensen
2018-09-06 09:07:35 +02:00
parent 96329fc290
commit c5ca50b654
+28 -40
View File
@@ -61,16 +61,17 @@ typedef struct {
struct pollfd fds[3]; struct pollfd fds[3];
struct termios tio;
unsigned char mcr;
char net_buf[NET_BUF_SIZE]; char net_buf[NET_BUF_SIZE];
size_t net_cnt; size_t net_cnt;
char tmp_buf[TMP_BUF_SIZE]; char tmp_buf[TMP_BUF_SIZE];
struct termios tio;
int cmcr;
int epipe; int epipe;
volatile sig_atomic_t error;
volatile sig_atomic_t pollin; volatile int smcr;
volatile int error;
volatile int pollin;
tn_ctx_t *tn; tn_ctx_t *tn;
} ttynvt_t; } ttynvt_t;
@@ -200,12 +201,7 @@ static void *_read_net(void *arg)
else else
break; break;
} }
else if (tty->fds[FD_NET].revents & (POLLERR | POLLHUP | POLLNVAL)) if (tty->fds[FD_NET].revents & POLLIN)
{
_log(LOG_ERR, "net io error\n");
break;
}
else if (tty->fds[FD_NET].revents & POLLIN)
{ {
res = read(tty->fds[FD_NET].fd, tty->net_buf + tty->net_cnt, res = read(tty->fds[FD_NET].fd, tty->net_buf + tty->net_cnt,
NET_BUF_SIZE - tty->net_cnt); NET_BUF_SIZE - tty->net_cnt);
@@ -334,25 +330,24 @@ static int _srv_read(void *cctx, int timeout)
static void _modem_status_cb(void *cctx, int status) static void _modem_status_cb(void *cctx, int status)
{ {
ttynvt_t *tty = cctx; ttynvt_t *tty = cctx;
int mcr = 0;
DBG("MCR: DSR=%c CTS=%c RI=%c CD=%c\n", DBG("MCR: DSR=%c CTS=%c RI=%c CD=%c\n",
status & TNS_STATE_DSR ? '1' : '0', status & TNS_STATE_DSR ? '1' : '0',
status & TNS_STATE_CTS ? '1' : '0', status & TNS_STATE_CTS ? '1' : '0',
status & TNS_STATE_RI ? '1' : '0', status & TNS_STATE_CD ? '1' : '0'); status & TNS_STATE_RI ? '1' : '0', status & TNS_STATE_CD ? '1' : '0');
pthread_mutex_lock(&tty->tty_lock);
tty->mcr &= ~(TIOCM_CD | TIOCM_RI | TIOCM_CTS | TIOCM_DSR);
if (status & TNS_STATE_CD) if (status & TNS_STATE_CD)
tty->mcr |= TIOCM_CD; mcr |= TIOCM_CD;
if (status & TNS_STATE_RI) if (status & TNS_STATE_RI)
tty->mcr |= TIOCM_RI; mcr |= TIOCM_RI;
if (status & TNS_STATE_CTS) if (status & TNS_STATE_CTS)
tty->mcr |= TIOCM_CTS; mcr |= TIOCM_CTS;
if (status & TNS_STATE_DSR) if (status & TNS_STATE_DSR)
tty->mcr |= TIOCM_DSR; mcr |= TIOCM_DSR;
pthread_mutex_lock(&tty->tty_lock);
tty->smcr = mcr;
pthread_mutex_unlock(&tty->tty_lock); pthread_mutex_unlock(&tty->tty_lock);
} }
@@ -615,6 +610,7 @@ ttynvt_ioctl(fuse_req_t req, int cmd, void *arg,
ttynvt_t *tty = (ttynvt_t *) (uintptr_t) info->fh; ttynvt_t *tty = (ttynvt_t *) (uintptr_t) info->fh;
struct winsize ws; struct winsize ws;
unsigned int tiocm = 0; unsigned int tiocm = 0;
int mcr;
static struct termios tio = { static struct termios tio = {
.c_cflag = B115200 | CS8 | PARODD | CREAD | CLOCAL, .c_cflag = B115200 | CS8 | PARODD | CREAD | CLOCAL,
}; };
@@ -677,15 +673,12 @@ ttynvt_ioctl(fuse_req_t req, int cmd, void *arg,
if (tio.c_cflag & CRTSCTS) if (tio.c_cflag & CRTSCTS)
telnet_rfc2217_ctl(tty->tn, TNS_CTL_CTSRTS); telnet_rfc2217_ctl(tty->tn, TNS_CTL_CTSRTS);
#if 1 if (!(tty->cmcr & TIOCM_DTR) && speed != B0)
pthread_mutex_lock(&tty->tty_lock);
if (!(tty->mcr & TIOCM_DTR) && speed != B0)
{ {
tty->mcr |= TIOCM_DTR; tty->cmcr |= TIOCM_DTR;
telnet_rfc2217_ctl(tty->tn, TNS_CTL_DTR_ON); telnet_rfc2217_ctl(tty->tn, TNS_CTL_DTR_ON);
} }
pthread_mutex_unlock(&tty->tty_lock);
#endif
DBG("termios: %u%c%u%u %cCTSRTS %cCREAD %cHUPCL %cCLOCAL\n", DBG("termios: %u%c%u%u %cCTSRTS %cCREAD %cHUPCL %cCLOCAL\n",
baudrate(speed), pstr[par], csize, sb, baudrate(speed), pstr[par], csize, sb,
tio.c_cflag & CRTSCTS ? '+' : '-', tio.c_cflag & CRTSCTS ? '+' : '-',
@@ -747,63 +740,58 @@ ttynvt_ioctl(fuse_req_t req, int cmd, void *arg,
case TIOCMGET: case TIOCMGET:
CHECK_BUF_OUT(sizeof(int)); CHECK_BUF_OUT(sizeof(int));
pthread_mutex_lock(&tty->tty_lock); pthread_mutex_lock(&tty->tty_lock);
fuse_reply_ioctl(req, 0, &tty->mcr, sizeof(int)); mcr = tty->cmcr | tty->smcr;
pthread_mutex_unlock(&tty->tty_lock); pthread_mutex_unlock(&tty->tty_lock);
fuse_reply_ioctl(req, 0, &mcr, sizeof(int));
break; break;
case TIOCMBIS: case TIOCMBIS:
CHECK_BUF_IN(sizeof(int)); CHECK_BUF_IN(sizeof(int));
tiocm = *(unsigned int *)in_buf; tiocm = *(unsigned int *)in_buf;
fuse_reply_ioctl(req, 0, 0, 0); fuse_reply_ioctl(req, 0, 0, 0);
DBG("%s: cmd=%s tiocm=%#x\n", __func__, _ioctl_name(cmd), tiocm); DBG("%s: cmd=%s tiocm=%#x\n", __func__, _ioctl_name(cmd), tiocm);
pthread_mutex_lock(&tty->tty_lock);
if (tiocm & TIOCM_RTS) if (tiocm & TIOCM_RTS)
{ {
tty->mcr |= TIOCM_RTS; tty->cmcr |= TIOCM_RTS;
telnet_rfc2217_ctl(tty->tn, TNS_CTL_RTS_ON); telnet_rfc2217_ctl(tty->tn, TNS_CTL_RTS_ON);
} }
if (tiocm & TIOCM_DTR) if (tiocm & TIOCM_DTR)
{ {
tty->mcr |= TIOCM_DTR; tty->cmcr |= TIOCM_DTR;
telnet_rfc2217_ctl(tty->tn, TNS_CTL_DTR_ON); telnet_rfc2217_ctl(tty->tn, TNS_CTL_DTR_ON);
} }
pthread_mutex_unlock(&tty->tty_lock);
goto show_mctl; goto show_mctl;
case TIOCMBIC: case TIOCMBIC:
CHECK_BUF_IN(sizeof(int)); CHECK_BUF_IN(sizeof(int));
tiocm = *(unsigned int *)in_buf; tiocm = *(unsigned int *)in_buf;
fuse_reply_ioctl(req, 0, 0, 0); fuse_reply_ioctl(req, 0, 0, 0);
DBG("%s: cmd=%s tiocm=%#x\n", __func__, _ioctl_name(cmd), tiocm); DBG("%s: cmd=%s tiocm=%#x\n", __func__, _ioctl_name(cmd), tiocm);
pthread_mutex_lock(&tty->tty_lock);
if (tiocm & TIOCM_RTS) if (tiocm & TIOCM_RTS)
{ {
tty->mcr &= ~TIOCM_RTS; tty->cmcr &= ~TIOCM_RTS;
telnet_rfc2217_ctl(tty->tn, TNS_CTL_RTS_OFF); telnet_rfc2217_ctl(tty->tn, TNS_CTL_RTS_OFF);
} }
if (tiocm & TIOCM_DTR) if (tiocm & TIOCM_DTR)
{ {
tty->mcr &= ~TIOCM_DTR; tty->cmcr &= ~TIOCM_DTR;
telnet_rfc2217_ctl(tty->tn, TNS_CTL_DTR_OFF); telnet_rfc2217_ctl(tty->tn, TNS_CTL_DTR_OFF);
} }
pthread_mutex_unlock(&tty->tty_lock);
goto show_mctl; goto show_mctl;
case TIOCMSET: case TIOCMSET:
CHECK_BUF_IN(sizeof(int)); CHECK_BUF_IN(sizeof(int));
tiocm = *(unsigned int *)in_buf; tiocm = *(unsigned int *)in_buf;
fuse_reply_ioctl(req, 0, 0, 0); fuse_reply_ioctl(req, 0, 0, 0);
DBG("%s: cmd=%s tiocm=%#x\n", __func__, _ioctl_name(cmd), tiocm); DBG("%s: cmd=%s tiocm=%#x\n", __func__, _ioctl_name(cmd), tiocm);
pthread_mutex_lock(&tty->tty_lock); tty->cmcr &= ~(TIOCM_RTS | TIOCM_DTR);
tty->mcr &= ~(TIOCM_RTS | TIOCM_DTR); tty->cmcr |= tiocm & (TIOCM_RTS | TIOCM_DTR);
tty->mcr |= tiocm & (TIOCM_RTS | TIOCM_DTR);
telnet_rfc2217_ctl(tty->tn, (tiocm & TIOCM_DTR) ? telnet_rfc2217_ctl(tty->tn, (tiocm & TIOCM_DTR) ?
TNS_CTL_DTR_ON : TNS_CTL_DTR_OFF); TNS_CTL_DTR_ON : TNS_CTL_DTR_OFF);
telnet_rfc2217_ctl(tty->tn, (tiocm & TIOCM_RTS) ? telnet_rfc2217_ctl(tty->tn, (tiocm & TIOCM_RTS) ?
TNS_CTL_RTS_ON : TNS_CTL_RTS_OFF); TNS_CTL_RTS_ON : TNS_CTL_RTS_OFF);
pthread_mutex_unlock(&tty->tty_lock);
goto show_mctl; goto show_mctl;
show_mctl: show_mctl:
DBG("MCR: DTR=%c RTS=%c\n", DBG("MCR: DTR=%c RTS=%c\n",
tty->mcr & TIOCM_DTR ? '1' : '0', tty->cmcr & TIOCM_DTR ? '1' : '0',
tty->mcr & TIOCM_RTS ? '1' : '0'); tty->cmcr & TIOCM_RTS ? '1' : '0');
break; break;
case TCSBRK: case TCSBRK:
fuse_reply_ioctl(req, 0, 0, 0); fuse_reply_ioctl(req, 0, 0, 0);