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 termios tio;
unsigned char mcr;
char net_buf[NET_BUF_SIZE];
size_t net_cnt;
char tmp_buf[TMP_BUF_SIZE];
struct termios tio;
int cmcr;
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;
} ttynvt_t;
@@ -200,12 +201,7 @@ static void *_read_net(void *arg)
else
break;
}
else if (tty->fds[FD_NET].revents & (POLLERR | POLLHUP | POLLNVAL))
{
_log(LOG_ERR, "net io error\n");
break;
}
else if (tty->fds[FD_NET].revents & POLLIN)
if (tty->fds[FD_NET].revents & POLLIN)
{
res = read(tty->fds[FD_NET].fd, tty->net_buf + 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)
{
ttynvt_t *tty = cctx;
int mcr = 0;
DBG("MCR: DSR=%c CTS=%c RI=%c CD=%c\n",
status & TNS_STATE_DSR ? '1' : '0',
status & TNS_STATE_CTS ? '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)
tty->mcr |= TIOCM_CD;
mcr |= TIOCM_CD;
if (status & TNS_STATE_RI)
tty->mcr |= TIOCM_RI;
mcr |= TIOCM_RI;
if (status & TNS_STATE_CTS)
tty->mcr |= TIOCM_CTS;
mcr |= TIOCM_CTS;
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);
}
@@ -615,6 +610,7 @@ ttynvt_ioctl(fuse_req_t req, int cmd, void *arg,
ttynvt_t *tty = (ttynvt_t *) (uintptr_t) info->fh;
struct winsize ws;
unsigned int tiocm = 0;
int mcr;
static struct termios tio = {
.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)
telnet_rfc2217_ctl(tty->tn, TNS_CTL_CTSRTS);
#if 1
pthread_mutex_lock(&tty->tty_lock);
if (!(tty->mcr & TIOCM_DTR) && speed != B0)
if (!(tty->cmcr & TIOCM_DTR) && speed != B0)
{
tty->mcr |= TIOCM_DTR;
tty->cmcr |= TIOCM_DTR;
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",
baudrate(speed), pstr[par], csize, sb,
tio.c_cflag & CRTSCTS ? '+' : '-',
@@ -747,63 +740,58 @@ ttynvt_ioctl(fuse_req_t req, int cmd, void *arg,
case TIOCMGET:
CHECK_BUF_OUT(sizeof(int));
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);
fuse_reply_ioctl(req, 0, &mcr, sizeof(int));
break;
case TIOCMBIS:
CHECK_BUF_IN(sizeof(int));
tiocm = *(unsigned int *)in_buf;
fuse_reply_ioctl(req, 0, 0, 0);
DBG("%s: cmd=%s tiocm=%#x\n", __func__, _ioctl_name(cmd), tiocm);
pthread_mutex_lock(&tty->tty_lock);
if (tiocm & TIOCM_RTS)
{
tty->mcr |= TIOCM_RTS;
tty->cmcr |= TIOCM_RTS;
telnet_rfc2217_ctl(tty->tn, TNS_CTL_RTS_ON);
}
if (tiocm & TIOCM_DTR)
{
tty->mcr |= TIOCM_DTR;
tty->cmcr |= TIOCM_DTR;
telnet_rfc2217_ctl(tty->tn, TNS_CTL_DTR_ON);
}
pthread_mutex_unlock(&tty->tty_lock);
goto show_mctl;
case TIOCMBIC:
CHECK_BUF_IN(sizeof(int));
tiocm = *(unsigned int *)in_buf;
fuse_reply_ioctl(req, 0, 0, 0);
DBG("%s: cmd=%s tiocm=%#x\n", __func__, _ioctl_name(cmd), tiocm);
pthread_mutex_lock(&tty->tty_lock);
if (tiocm & TIOCM_RTS)
{
tty->mcr &= ~TIOCM_RTS;
tty->cmcr &= ~TIOCM_RTS;
telnet_rfc2217_ctl(tty->tn, TNS_CTL_RTS_OFF);
}
if (tiocm & TIOCM_DTR)
{
tty->mcr &= ~TIOCM_DTR;
tty->cmcr &= ~TIOCM_DTR;
telnet_rfc2217_ctl(tty->tn, TNS_CTL_DTR_OFF);
}
pthread_mutex_unlock(&tty->tty_lock);
goto show_mctl;
case TIOCMSET:
CHECK_BUF_IN(sizeof(int));
tiocm = *(unsigned int *)in_buf;
fuse_reply_ioctl(req, 0, 0, 0);
DBG("%s: cmd=%s tiocm=%#x\n", __func__, _ioctl_name(cmd), tiocm);
pthread_mutex_lock(&tty->tty_lock);
tty->mcr &= ~(TIOCM_RTS | TIOCM_DTR);
tty->mcr |= tiocm & (TIOCM_RTS | TIOCM_DTR);
tty->cmcr &= ~(TIOCM_RTS | TIOCM_DTR);
tty->cmcr |= tiocm & (TIOCM_RTS | TIOCM_DTR);
telnet_rfc2217_ctl(tty->tn, (tiocm & TIOCM_DTR) ?
TNS_CTL_DTR_ON : TNS_CTL_DTR_OFF);
telnet_rfc2217_ctl(tty->tn, (tiocm & TIOCM_RTS) ?
TNS_CTL_RTS_ON : TNS_CTL_RTS_OFF);
pthread_mutex_unlock(&tty->tty_lock);
goto show_mctl;
show_mctl:
DBG("MCR: DTR=%c RTS=%c\n",
tty->mcr & TIOCM_DTR ? '1' : '0',
tty->mcr & TIOCM_RTS ? '1' : '0');
tty->cmcr & TIOCM_DTR ? '1' : '0',
tty->cmcr & TIOCM_RTS ? '1' : '0');
break;
case TCSBRK:
fuse_reply_ioctl(req, 0, 0, 0);