Serial Multiplexer cleanup after review by Dave Bryan

- Added functionality to return the lines with attached serial ports by calling tmxr_poll_conn one time after a serial port is attached.
- Added the ability to close a serial port from the sim> prompt if a device implements a SET dev DISCONNECT=line command.  A serial port is closed if the -C switch is specified on the DISCONNECT command line.
- Cleaned up the multiplexer status display based on Dave's recommendations.
This commit is contained in:
Mark Pizzolato 2012-12-13 13:46:43 -08:00
parent b466bdc9c6
commit 59afee3128
2 changed files with 123 additions and 90 deletions

View file

@ -255,10 +255,18 @@
A device emulation may choose to implement a command interface to
disconnect specific individual lines. This would usually be done via
a Unit Modifier table entry (MTAB) which dispatches the command
"SET dev DISCONNECT[=line]" to tmxr_detach_line.
"SET dev DISCONNECT[=line]" to tmxr_dscln. This will cause a telnet
connection to be closed, but a serial port will normally have DTR
dropped for 500ms and raised again (thus hanging up a modem on that
serial port).
sim> set MUX disconnect=2
A line which is connected to a serial port can be manually closed by
adding the -C switch to a disconnect command.
sim> set -C MUX disconnect=2
Full Modem Control serial port support.
This library supports devices which wish to emulate full modem
@ -717,6 +725,7 @@ mp->last_poll_time = poll_time;
/* Check for a pending Telnet connection */
if (mp->master) {
newsock = sim_accept_conn (mp->master, &address); /* poll connect */
if (newsock != INVALID_SOCKET) { /* got a live one? */
@ -760,6 +769,7 @@ if (newsock != INVALID_SOCKET) { /* got a live one? */
return i;
}
} /* end if newsock */
}
/* Look for per line listeners or outbound connecting sockets */
for (i = 0; i < mp->lines; i++) { /* check each line in sequence */
@ -781,6 +791,8 @@ for (i = 0; i < mp->lines; i++) { /* check each line in se
/* Check for a pending Telnet connection */
if (lp->master) {
newsock = sim_accept_conn (lp->master, &address);/* poll connect */
if (newsock != INVALID_SOCKET) { /* got a live one? */
@ -825,6 +837,14 @@ for (i = 0; i < mp->lines; i++) { /* check each line in se
}
}
/* Check for pending serial port connection notification */
if (lp->ser_connect_pending) {
lp->ser_connect_pending = FALSE;
return i;
}
}
return -1; /* no new connections made */
}
@ -832,8 +852,9 @@ return -1; /* no new connections ma
The telnet/tcp or serial session associated with multiplexer descriptor "mp" and
line descriptor "lp" is disconnected. An associated tcp socket is
deallocated; a serial port is not, although for non modem control serial lines
DTR is dropped and raised again after 500ms to signal the attached serial device.
closed; a serial port is closed if the closeserial parameter is true, otherwise
for non modem control serial lines DTR is dropped and raised again after 500ms
to signal the attached serial device.
*/
static t_stat tmxr_reset_ln_ex (TMLN *lp, t_bool closeserial)
@ -847,6 +868,9 @@ if (lp->serport) {
if (closeserial) {
sim_close_serial (lp->serport);
lp->serport = 0;
lp->ser_connect_pending = FALSE;
free (lp->destination);
lp->destination = NULL;
free (lp->serconfig);
lp->serconfig = NULL;
lp->cnms = 0;
@ -879,6 +903,11 @@ else {
tmxr_init_line (lp); /* initialize line state */
lp->conn = 0; /* remove socket or connection flag */
}
/* Revise the unit's connect string to reflect the current attachments */
lp->mp->uptr->filename = _mux_attach_string (lp->mp->uptr->filename, lp->mp);
/* No connections or listeners exist, then we're equivalent to being fully detached. We should reflect that */
if (lp->mp->uptr->filename == NULL)
tmxr_detach (lp->mp, lp->mp->uptr);
return SCPE_OK;
}
@ -1572,6 +1601,7 @@ while (*tptr) {
if (serport != INVALID_HANDLE) {
lp->mp = mp;
lp->serport = serport;
lp->ser_connect_pending = TRUE;
lp->notelnet = TRUE;
tmxr_init_line (lp); /* init the line state */
if (!lp->mp->modem_control) /* raise DTR and RTS for non modem control lines */
@ -1677,6 +1707,7 @@ while (*tptr) {
serport = sim_open_serial (lp->destination, lp, &r);
if (serport != INVALID_HANDLE) {
lp->serport = serport;
lp->ser_connect_pending = TRUE;
lp->notelnet = TRUE;
tmxr_init_line (lp); /* init the line state */
if (!lp->mp->modem_control) /* raise DTR and RTS for non modem control lines */
@ -2016,12 +2047,11 @@ return SCPE_OK;
}
/* Detach unit from master socket.
/* Detach unit from master socket and close all active network connections
and/or serial ports.
Note that we return SCPE_OK, regardless of whether a listening socket was
attached. For single-line multiplexers that may be attached either to a
listening socket or to a serial port, call "tmxr_detach_line" first. If that
routine returns SCPE_UNATT, then call "tmxr_detach".
attached.
*/
t_stat tmxr_detach (TMXR *mp, UNIT *uptr)
@ -2119,17 +2149,19 @@ static const char *enab = "on";
static const char *dsab = "off";
if (ln >= 0)
fprintf (st, "line %d:\b", ln);
fprintf (st, "line %d:\n", ln);
if ((!lp->conn) && (!lp->connecting) && (!lp->serport))
fprintf (st, "line disconnected\n");
if (lp->rxcnt)
else {
if ((lp->rxcnt) || (!lp->rcve))
fprintf (st, " input (%s) queued/total = %d/%d\n",
(lp->rcve? enab: dsab),
tmxr_rqln (lp), lp->rxcnt);
if (lp->txcnt || lp->txbpi)
if (lp->txcnt || lp->txbpi || (!lp->xmte))
fprintf (st, " output (%s) queued/total = %d/%d\n",
(lp->xmte? enab: dsab),
tmxr_tqln (lp), lp->txcnt);
}
if (lp->txbfd)
fprintf (st, " output buffer size = %d\n", lp->txbsz);
if (lp->txcnt || lp->txbpi)
@ -2185,7 +2217,7 @@ if (lp == NULL) /* bad line numb
if ((lp->conn) || (lp->serport)) { /* connection active? */
if (!lp->notelnet)
tmxr_linemsg (lp, "\r\nOperator disconnected line\r\n\n");/* report closure */
tmxr_reset_ln (lp); /* drop the line */
tmxr_reset_ln_ex (lp, (sim_switches & SWMASK ('C'))); /* drop the line */
}
return SCPE_OK;

View file

@ -116,6 +116,7 @@ struct tmln {
TMXR *mp; /* back pointer to mux */
char *serconfig; /* line config */
SERHANDLE serport; /* serial port handle */
t_bool ser_connect_pending; /* serial connection notice pending */
SOCKET connecting; /* Outgoing socket while connecting */
char *destination; /* Outgoing destination address:port */
UNIT *uptr; /* input polling unit (default to mp->uptr) */