1
0
mirror of https://github.com/simh/simh.git synced 2026-01-11 23:52:58 +00:00

Merge latest tmxr from old repo

This commit is contained in:
Timothe Litt 2013-07-05 06:18:30 -04:00
parent faf77b008a
commit 467de41bc4
2 changed files with 180 additions and 21 deletions

View File

@ -67,8 +67,10 @@
tmxr_reset_ln - reset line (drops Telnet/tcp and serial connections)
tmxr_detach_ln - reset line and close per line listener and outgoing destination
tmxr_getc_ln - get character for line
tmxr_get_packet_ln - get packet from line
tmxr_poll_rx - poll receive
tmxr_putc_ln - put character for line
tmxr_put_packet_ln - put packet on line
tmxr_poll_tx - poll transmit
tmxr_send_buffered_data - transmit buffered data
tmxr_set_modem_control_passthru - enable modem control on a multiplexer
@ -94,6 +96,8 @@
tmxr_dscln - disconnect line (SET routine)
tmxr_rqln - number of available characters for line
tmxr_tqln - number of buffered characters for line
tmxr_tpqln - number of buffered packet characters for line
tmxr_tpbusyln - transmit packet busy status for line
tmxr_set_lnorder - set line connection order
tmxr_show_lnorder - show line connection order
tmxr_show_summ - show connection summary
@ -435,9 +439,9 @@ static void tmxr_init_line (TMLN *lp)
lp->tsta = 0; /* init telnet state */
lp->xmte = 1; /* enable transmit */
lp->dstb = 0; /* default bin mode */
lp->rxbpr = lp->rxbpi = lp->rxcnt = 0; /* init receive indexes */
lp->rxbpr = lp->rxbpi = lp->rxcnt = lp->rxpcnt = 0; /* init receive indexes */
if (!lp->txbfd || lp->notelnet) /* if not buffered telnet */
lp->txbpr = lp->txbpi = lp->txcnt = 0; /* init transmit indexes */
lp->txbpr = lp->txbpi = lp->txcnt = lp->txpcnt = 0; /* init transmit indexes */
memset (lp->rbr, 0, sizeof(lp->rbr)); /* clear break status array */
lp->txdrp = 0;
if (lp->modem_control) {
@ -449,6 +453,16 @@ if ((!lp->mp->buffered) && (!lp->txbfd)) {
lp->txbsz = TMXR_MAXBUF;
lp->txb = (char *)realloc (lp->txb, lp->txbsz);
}
if (lp->rxpb) {
lp->rxpboffset = lp->rxpbsize = 0;
free (lp->rxpb);
lp->rxpb = NULL;
}
if (lp->txpb) {
lp->txpbsize = lp->txppsize = lp->txppoffset = 0;
free (lp->txpb);
lp->txpb = NULL;
}
return;
}
@ -492,6 +506,7 @@ if (!mp->buffered) {
lp->txbpi = 0; /* init buf pointers */
lp->txbpr = (int32)(lp->txbsz - strlen (msgbuf));
lp->rxcnt = lp->txcnt = lp->txdrp = 0; /* init counters */
lp->rxpcnt = lp->txpcnt = 0;
}
else
if (lp->txcnt > lp->txbsz)
@ -930,7 +945,7 @@ for (i = 0; i < mp->lines; i++) { /* check each line in se
lp->conn = TRUE; /* record connection */
lp->sock = lp->connecting; /* it now looks normal */
lp->connecting = 0;
lp->ipad = realloc (lp->ipad, 1+strlen (lp->destination));
lp->ipad = (char *)realloc (lp->ipad, 1+strlen (lp->destination));
strcpy (lp->ipad, lp->destination);
lp->cnms = sim_os_msec ();
sim_getnames_sock (lp->sock, &sockname, &peername);
@ -1203,7 +1218,7 @@ return tmxr_clear_modem_control_passthru_state (mp, FALSE);
Implementation note:
If a line is connected to a serial port, then these valus affect
If a line is connected to a serial port, then these values affect
and reflect the state of the serial port. If the line is connected
to a network socket (or could be) then the network session state is
set, cleared and/or returned.
@ -1320,6 +1335,59 @@ if (lp->rxbpi == lp->rxbpr) /* empty? zero ptrs */
return val;
}
/* Get packet from specific line
Inputs:
*lp = pointer to terminal line descriptor
**pbuf = pointer to pointer of packet contents
*psize = pointer to packet size
Output:
SCPE_LOST link state lost
SCPE_OK Packet returned OR no packet available
Implementation notes:
1. If a packet is not yet available, then the pbuf address returned is
NULL, but success (SCPE_OK) is returned
receive break status associated with the character is cleared, and
SCPE_BREAK is ORed into the return value.
*/
t_stat tmxr_get_packet_ln (TMLN *lp, const uint8 **pbuf, size_t *psize)
{
int32 c;
size_t pktsize;
while (TMXR_VALID & (c = tmxr_getc_ln (lp))) {
if (lp->rxpboffset + 1 > lp->rxpbsize) {
lp->rxpbsize += 512;
lp->rxpb = (uint8 *)realloc (lp->rxpb, lp->rxpbsize);
}
lp->rxpb[lp->rxpboffset] = c;
if ((lp->rxpboffset == 0) && (c != 0x1E)) {
tmxr_debug (TMXR_DBG_PRCV, lp, "Received Unexpected Byte", (char *)&lp->rxpb[lp->rxpboffset], 1);
continue;
}
lp->rxpboffset += 1;
if (lp->rxpboffset >= 3) {
pktsize = (lp->rxpb[1] << 8) | lp->rxpb[2];
if (pktsize == (lp->rxpboffset - 2)) {
++lp->rxpcnt;
*pbuf = &lp->rxpb[3];
*psize = pktsize;
lp->rxpboffset = 0;
tmxr_debug (TMXR_DBG_PRCV, lp, "Received Packet", (char *)&lp->rxpb[3], pktsize);
return SCPE_OK;
}
}
}
*pbuf = NULL;
*psize = 0;
if (lp->conn)
return SCPE_OK;
return SCPE_LOST;
}
/* Poll for input
@ -1526,6 +1594,51 @@ if ((lp->txbfd && !lp->notelnet) || (TXBUF_AVAIL(lp) > 1)) {/* room for char (+
return SCPE_STALL; /* char not sent */
}
/* Store packet in line buffer
Inputs:
*lp = pointer to line descriptor
*buf = pointer to packet data
size = size of packet
Outputs:
status = ok, connection lost, or stall
Implementation notea:
1. If the line is not connected, SCPE_LOST is returned.
2. If prior packet transmission still in progress, SCPE_STALL is
returned and no packet data is stored. The caller must retry later.
*/
t_stat tmxr_put_packet_ln (TMLN *lp, const uint8 *buf, size_t size)
{
t_stat r;
if (!lp->conn)
return SCPE_LOST;
if (lp->txppoffset < lp->txppsize) {
tmxr_debug (TMXR_DBG_PXMT, lp, "Skipped Sending Packet - Transmit Busy", (char *)&lp->txpb[3], size);
return SCPE_STALL;
}
if (lp->txpbsize < size + 3) {
lp->txpbsize = size + 3;
lp->txpb = (uint8 *)realloc (lp->txpb, lp->txpbsize);
}
lp->txpb[0] = 0x1E; /* Record Separator to Frame packet */
lp->txpb[1] = (size >> 8) & 0xFF;
lp->txpb[2] = size & 0xFF;
memcpy (lp->txpb + 3, buf, size);
lp->txppsize = size + 3;
lp->txppoffset = 0;
tmxr_debug (TMXR_DBG_PXMT, lp, "Sending Packet", (char *)&lp->txpb[3], size);
++lp->txpcnt;
while ((lp->txppoffset < lp->txppsize) &&
(SCPE_OK == (r = tmxr_putc_ln (lp, lp->txpb[lp->txppoffset]))))
++lp->txppoffset;
tmxr_send_buffered_data (lp);
return lp->conn ? SCPE_OK : SCPE_LOST;
}
/* Poll for output
Inputs:
@ -1571,6 +1684,7 @@ return;
int32 tmxr_send_buffered_data (TMLN *lp)
{
int32 nbytes, sbytes;
t_stat r;
tmxr_debug_trace_line (lp, "tmxr_send_buffered_data()");
nbytes = tmxr_tqln(lp); /* avail bytes */
@ -1590,6 +1704,7 @@ if (nbytes) { /* >0? write */
}
if (sbytes < 0) { /* I/O Error? */
lp->txbpi = lp->txbpr = 0; /* Drop the data we already know we can't send */
lp->rxpboffset = lp->txppoffset = lp->txppsize = 0;/* Drop the data we already know we can't send */
tmxr_close_ln (lp); /* close line/port on error */
return nbytes; /* done now. */
}
@ -1605,7 +1720,13 @@ if (nbytes) { /* >0? write */
}
}
} /* end if nbytes */
return nbytes;
while ((lp->txppoffset < lp->txppsize) && /* buffered packet data? */
(lp->txbsz > nbytes) && /* and room in xmt buffer */
(SCPE_OK == (r = tmxr_putc_ln (lp, lp->txpb[lp->txppoffset]))))
++lp->txppoffset;
if ((nbytes == 0) && (tmxr_tqln(lp) > 0))
return tmxr_send_buffered_data (lp);
return tmxr_tqln(lp) + tmxr_tpqln(lp);
}
@ -1616,6 +1737,20 @@ int32 tmxr_tqln (TMLN *lp)
return (lp->txbpi - lp->txbpr + ((lp->txbpi < lp->txbpr)? lp->txbsz: 0));
}
/* Return count of buffered packet characters for line */
int32 tmxr_tpqln (TMLN *lp)
{
return (lp->txppsize - lp->txppoffset);
}
/* Return transmit packet busy status for line */
t_bool tmxr_tpbusyln (TMLN *lp)
{
return (0 != (lp->txppsize - lp->txppoffset));
}
static void _mux_detach_line (TMLN *lp, t_bool close_listener, t_bool close_connecting)
{
if (close_listener && lp->master) {
@ -1932,7 +2067,7 @@ while (*tptr) {
free (lp->mp->port);
lp->mp->port = NULL;
}
lp->destination = malloc(1+strlen(destination));
lp->destination = (char *)malloc(1+strlen(destination));
strcpy (lp->destination, destination);
lp->mp = mp;
lp->serport = serport;
@ -1951,14 +2086,17 @@ while (*tptr) {
sock = sim_connect_sock (destination, "localhost", NULL);
if (sock != INVALID_SOCKET) {
_mux_detach_line (lp, FALSE, TRUE);
lp->destination = malloc(1+strlen(destination));
lp->destination = (char *)malloc(1+strlen(destination));
strcpy (lp->destination, destination);
lp->mp = mp;
lp->connecting = sock;
lp->ipad = malloc (1 + strlen (lp->destination));
strcpy (lp->ipad, lp->destination);
if (!lp->modem_control || (lp->modembits & TMXR_MDM_DTR)) {
lp->connecting = sock;
lp->ipad = (char *)malloc (1 + strlen (lp->destination));
strcpy (lp->ipad, lp->destination);
}
else
sim_close_sock (sock, FALSE);
lp->notelnet = notelnet;
lp->cnms = sim_os_msec (); /* record time of connection */
tmxr_init_line (lp); /* init the line state */
return SCPE_OK;
}
@ -2027,7 +2165,7 @@ while (*tptr) {
serport = sim_open_serial (destination, lp, &r);
if (serport != INVALID_HANDLE) {
_mux_detach_line (lp, TRUE, TRUE);
lp->destination = malloc(1+strlen(destination));
lp->destination = (char *)malloc(1+strlen(destination));
strcpy (lp->destination, destination);
lp->serport = serport;
lp->ser_connect_pending = TRUE;
@ -2045,13 +2183,16 @@ while (*tptr) {
sock = sim_connect_sock (destination, "localhost", NULL);
if (sock != INVALID_SOCKET) {
_mux_detach_line (lp, FALSE, TRUE);
lp->destination = malloc(1+strlen(destination));
lp->destination = (char *)malloc(1+strlen(destination));
strcpy (lp->destination, destination);
lp->connecting = sock;
lp->ipad = malloc (1 + strlen (lp->destination));
strcpy (lp->ipad, lp->destination);
if (!lp->modem_control || (lp->modembits & TMXR_MDM_DTR)) {
lp->connecting = sock;
lp->ipad = (char *)malloc (1 + strlen (lp->destination));
strcpy (lp->ipad, lp->destination);
}
else
sim_close_sock (sock, FALSE);
lp->notelnet = notelnet;
lp->cnms = sim_os_msec (); /* record time of connection */
tmxr_init_line (lp); /* init the line state */
}
else
@ -3343,12 +3484,15 @@ else {
fprintf (st, "\n");
fprintf (st, " input (%s)", (lp->rcve? enab: dsab));
if (lp->rxcnt)
fprintf (st, " queued/total = %d/%d",
tmxr_rqln (lp), lp->rxcnt);
fprintf (st, " queued/total = %d/%d", tmxr_rqln (lp), lp->rxcnt);
if (lp->rxpcnt)
fprintf (st, " packets = %d", lp->rxpcnt);
fprintf (st, "\n output (%s)", (lp->xmte? enab: dsab));
if (lp->txcnt || lp->txbpi)
fprintf (st, " queued/total = %d/%d",
tmxr_tqln (lp), lp->txcnt);
fprintf (st, " queued/total = %d/%d", tmxr_tqln (lp), lp->txcnt);
if (lp->txpcnt || tmxr_tpqln (lp))
fprintf (st, " packet data queued/packets sent = %d/%d",
tmxr_tpqln (lp), lp->txpcnt);
fprintf (st, "\n");
}
if (lp->txbfd)

View File

@ -72,6 +72,8 @@ typedef int SERHANDLE;
#define TMXR_DBG_CON 0x080000 /* Debug Connection Activities */
#define TMXR_DBG_ASY 0x100000 /* Debug Asynchronous Activities */
#define TMXR_DBG_TRC 0x200000 /* Debug trace routine calls */
#define TMXR_DBG_PXMT 0x400000 /* Debug Transmit Packet Data */
#define TMXR_DBG_PRCV 0x800000 /* Debug Received Packet Data */
/* Modem Control Bits */
@ -111,9 +113,11 @@ struct tmln {
int32 rxbpr; /* rcv buf remove */
int32 rxbpi; /* rcv buf insert */
int32 rxcnt; /* rcv count */
int32 rxpcnt; /* rcv packet count */
int32 txbpr; /* xmt buf remove */
int32 txbpi; /* xmt buf insert */
int32 txcnt; /* xmt count */
int32 txpcnt; /* xmt packet count */
int32 txdrp; /* xmt drop count */
int32 txbsz; /* xmt buffer size */
int32 txbfd; /* xmt buffered flag */
@ -125,6 +129,13 @@ struct tmln {
char rxb[TMXR_MAXBUF]; /* rcv buffer */
char rbr[TMXR_MAXBUF]; /* rcv break */
char *txb; /* xmt buffer */
uint8 *rxpb; /* rcv packet buffer */
uint32 rxpbsize; /* rcv packet buffer size */
uint32 rxpboffset; /* rcv packet buffer offset */
uint8 *txpb; /* xmt packet buffer */
uint32 txpbsize; /* xmt packet buffer size */
uint32 txppsize; /* xmt packet packet size */
uint32 txppoffset; /* xmt packet buffer offset */
TMXR *mp; /* back pointer to mux */
char *serconfig; /* line config */
SERHANDLE serport; /* serial port handle */
@ -156,8 +167,10 @@ int32 tmxr_poll_conn (TMXR *mp);
t_stat tmxr_reset_ln (TMLN *lp);
t_stat tmxr_detach_ln (TMLN *lp);
int32 tmxr_getc_ln (TMLN *lp);
t_stat tmxr_get_packet_ln (TMLN *lp, const uint8 **pbuf, size_t *psize);
void tmxr_poll_rx (TMXR *mp);
t_stat tmxr_putc_ln (TMLN *lp, int32 chr);
t_stat tmxr_put_packet_ln (TMLN *lp, const uint8 *buf, size_t size);
void tmxr_poll_tx (TMXR *mp);
int32 tmxr_send_buffered_data (TMLN *lp);
t_stat tmxr_open_master (TMXR *mp, char *cptr);
@ -186,6 +199,8 @@ t_stat tmxr_show_log (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat tmxr_dscln (UNIT *uptr, int32 val, char *cptr, void *desc);
int32 tmxr_rqln (TMLN *lp);
int32 tmxr_tqln (TMLN *lp);
int32 tmxr_tpqln (TMLN *lp);
t_bool tmxr_tpbusyln (TMLN *lp);
t_stat tmxr_set_lnorder (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat tmxr_show_lnorder (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat tmxr_show_summ (FILE *st, UNIT *uptr, int32 val, void *desc);