improved handling of modem/line status
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user