1
0
mirror of https://github.com/open-simh/simh.git synced 2026-04-26 04:07:23 +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_reset_ln - reset line (drops Telnet/tcp and serial connections)
tmxr_detach_ln - reset line and close per line listener and outgoing destination tmxr_detach_ln - reset line and close per line listener and outgoing destination
tmxr_getc_ln - get character for line tmxr_getc_ln - get character for line
tmxr_get_packet_ln - get packet from line
tmxr_poll_rx - poll receive tmxr_poll_rx - poll receive
tmxr_putc_ln - put character for line tmxr_putc_ln - put character for line
tmxr_put_packet_ln - put packet on line
tmxr_poll_tx - poll transmit tmxr_poll_tx - poll transmit
tmxr_send_buffered_data - transmit buffered data tmxr_send_buffered_data - transmit buffered data
tmxr_set_modem_control_passthru - enable modem control on a multiplexer tmxr_set_modem_control_passthru - enable modem control on a multiplexer
@@ -94,6 +96,8 @@
tmxr_dscln - disconnect line (SET routine) tmxr_dscln - disconnect line (SET routine)
tmxr_rqln - number of available characters for line tmxr_rqln - number of available characters for line
tmxr_tqln - number of buffered 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_set_lnorder - set line connection order
tmxr_show_lnorder - show line connection order tmxr_show_lnorder - show line connection order
tmxr_show_summ - show connection summary tmxr_show_summ - show connection summary
@@ -435,9 +439,9 @@ static void tmxr_init_line (TMLN *lp)
lp->tsta = 0; /* init telnet state */ lp->tsta = 0; /* init telnet state */
lp->xmte = 1; /* enable transmit */ lp->xmte = 1; /* enable transmit */
lp->dstb = 0; /* default bin mode */ 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 */ 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 */ memset (lp->rbr, 0, sizeof(lp->rbr)); /* clear break status array */
lp->txdrp = 0; lp->txdrp = 0;
if (lp->modem_control) { if (lp->modem_control) {
@@ -449,6 +453,16 @@ if ((!lp->mp->buffered) && (!lp->txbfd)) {
lp->txbsz = TMXR_MAXBUF; lp->txbsz = TMXR_MAXBUF;
lp->txb = (char *)realloc (lp->txb, lp->txbsz); 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; return;
} }
@@ -492,6 +506,7 @@ if (!mp->buffered) {
lp->txbpi = 0; /* init buf pointers */ lp->txbpi = 0; /* init buf pointers */
lp->txbpr = (int32)(lp->txbsz - strlen (msgbuf)); lp->txbpr = (int32)(lp->txbsz - strlen (msgbuf));
lp->rxcnt = lp->txcnt = lp->txdrp = 0; /* init counters */ lp->rxcnt = lp->txcnt = lp->txdrp = 0; /* init counters */
lp->rxpcnt = lp->txpcnt = 0;
} }
else else
if (lp->txcnt > lp->txbsz) 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->conn = TRUE; /* record connection */
lp->sock = lp->connecting; /* it now looks normal */ lp->sock = lp->connecting; /* it now looks normal */
lp->connecting = 0; 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); strcpy (lp->ipad, lp->destination);
lp->cnms = sim_os_msec (); lp->cnms = sim_os_msec ();
sim_getnames_sock (lp->sock, &sockname, &peername); sim_getnames_sock (lp->sock, &sockname, &peername);
@@ -1203,7 +1218,7 @@ return tmxr_clear_modem_control_passthru_state (mp, FALSE);
Implementation note: 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 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 to a network socket (or could be) then the network session state is
set, cleared and/or returned. set, cleared and/or returned.
@@ -1320,6 +1335,59 @@ if (lp->rxbpi == lp->rxbpr) /* empty? zero ptrs */
return val; 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 /* 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 */ 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 /* Poll for output
Inputs: Inputs:
@@ -1571,6 +1684,7 @@ return;
int32 tmxr_send_buffered_data (TMLN *lp) int32 tmxr_send_buffered_data (TMLN *lp)
{ {
int32 nbytes, sbytes; int32 nbytes, sbytes;
t_stat r;
tmxr_debug_trace_line (lp, "tmxr_send_buffered_data()"); tmxr_debug_trace_line (lp, "tmxr_send_buffered_data()");
nbytes = tmxr_tqln(lp); /* avail bytes */ nbytes = tmxr_tqln(lp); /* avail bytes */
@@ -1590,6 +1704,7 @@ if (nbytes) { /* >0? write */
} }
if (sbytes < 0) { /* I/O Error? */ if (sbytes < 0) { /* I/O Error? */
lp->txbpi = lp->txbpr = 0; /* Drop the data we already know we can't send */ 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 */ tmxr_close_ln (lp); /* close line/port on error */
return nbytes; /* done now. */ return nbytes; /* done now. */
} }
@@ -1605,7 +1720,13 @@ if (nbytes) { /* >0? write */
} }
} }
} /* end if nbytes */ } /* 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 (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) static void _mux_detach_line (TMLN *lp, t_bool close_listener, t_bool close_connecting)
{ {
if (close_listener && lp->master) { if (close_listener && lp->master) {
@@ -1932,7 +2067,7 @@ while (*tptr) {
free (lp->mp->port); free (lp->mp->port);
lp->mp->port = NULL; lp->mp->port = NULL;
} }
lp->destination = malloc(1+strlen(destination)); lp->destination = (char *)malloc(1+strlen(destination));
strcpy (lp->destination, destination); strcpy (lp->destination, destination);
lp->mp = mp; lp->mp = mp;
lp->serport = serport; lp->serport = serport;
@@ -1951,14 +2086,17 @@ while (*tptr) {
sock = sim_connect_sock (destination, "localhost", NULL); sock = sim_connect_sock (destination, "localhost", NULL);
if (sock != INVALID_SOCKET) { if (sock != INVALID_SOCKET) {
_mux_detach_line (lp, FALSE, TRUE); _mux_detach_line (lp, FALSE, TRUE);
lp->destination = malloc(1+strlen(destination)); lp->destination = (char *)malloc(1+strlen(destination));
strcpy (lp->destination, destination); strcpy (lp->destination, destination);
lp->mp = mp; lp->mp = mp;
lp->connecting = sock; if (!lp->modem_control || (lp->modembits & TMXR_MDM_DTR)) {
lp->ipad = malloc (1 + strlen (lp->destination)); lp->connecting = sock;
strcpy (lp->ipad, lp->destination); lp->ipad = (char *)malloc (1 + strlen (lp->destination));
strcpy (lp->ipad, lp->destination);
}
else
sim_close_sock (sock, FALSE);
lp->notelnet = notelnet; lp->notelnet = notelnet;
lp->cnms = sim_os_msec (); /* record time of connection */
tmxr_init_line (lp); /* init the line state */ tmxr_init_line (lp); /* init the line state */
return SCPE_OK; return SCPE_OK;
} }
@@ -2027,7 +2165,7 @@ while (*tptr) {
serport = sim_open_serial (destination, lp, &r); serport = sim_open_serial (destination, lp, &r);
if (serport != INVALID_HANDLE) { if (serport != INVALID_HANDLE) {
_mux_detach_line (lp, TRUE, TRUE); _mux_detach_line (lp, TRUE, TRUE);
lp->destination = malloc(1+strlen(destination)); lp->destination = (char *)malloc(1+strlen(destination));
strcpy (lp->destination, destination); strcpy (lp->destination, destination);
lp->serport = serport; lp->serport = serport;
lp->ser_connect_pending = TRUE; lp->ser_connect_pending = TRUE;
@@ -2045,13 +2183,16 @@ while (*tptr) {
sock = sim_connect_sock (destination, "localhost", NULL); sock = sim_connect_sock (destination, "localhost", NULL);
if (sock != INVALID_SOCKET) { if (sock != INVALID_SOCKET) {
_mux_detach_line (lp, FALSE, TRUE); _mux_detach_line (lp, FALSE, TRUE);
lp->destination = malloc(1+strlen(destination)); lp->destination = (char *)malloc(1+strlen(destination));
strcpy (lp->destination, destination); strcpy (lp->destination, destination);
lp->connecting = sock; if (!lp->modem_control || (lp->modembits & TMXR_MDM_DTR)) {
lp->ipad = malloc (1 + strlen (lp->destination)); lp->connecting = sock;
strcpy (lp->ipad, lp->destination); lp->ipad = (char *)malloc (1 + strlen (lp->destination));
strcpy (lp->ipad, lp->destination);
}
else
sim_close_sock (sock, FALSE);
lp->notelnet = notelnet; lp->notelnet = notelnet;
lp->cnms = sim_os_msec (); /* record time of connection */
tmxr_init_line (lp); /* init the line state */ tmxr_init_line (lp); /* init the line state */
} }
else else
@@ -3343,12 +3484,15 @@ else {
fprintf (st, "\n"); fprintf (st, "\n");
fprintf (st, " input (%s)", (lp->rcve? enab: dsab)); fprintf (st, " input (%s)", (lp->rcve? enab: dsab));
if (lp->rxcnt) if (lp->rxcnt)
fprintf (st, " queued/total = %d/%d", fprintf (st, " queued/total = %d/%d", tmxr_rqln (lp), lp->rxcnt);
tmxr_rqln (lp), lp->rxcnt); if (lp->rxpcnt)
fprintf (st, " packets = %d", lp->rxpcnt);
fprintf (st, "\n output (%s)", (lp->xmte? enab: dsab)); fprintf (st, "\n output (%s)", (lp->xmte? enab: dsab));
if (lp->txcnt || lp->txbpi) if (lp->txcnt || lp->txbpi)
fprintf (st, " queued/total = %d/%d", fprintf (st, " queued/total = %d/%d", tmxr_tqln (lp), lp->txcnt);
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"); fprintf (st, "\n");
} }
if (lp->txbfd) if (lp->txbfd)

View File

@@ -72,6 +72,8 @@ typedef int SERHANDLE;
#define TMXR_DBG_CON 0x080000 /* Debug Connection Activities */ #define TMXR_DBG_CON 0x080000 /* Debug Connection Activities */
#define TMXR_DBG_ASY 0x100000 /* Debug Asynchronous Activities */ #define TMXR_DBG_ASY 0x100000 /* Debug Asynchronous Activities */
#define TMXR_DBG_TRC 0x200000 /* Debug trace routine calls */ #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 */ /* Modem Control Bits */
@@ -111,9 +113,11 @@ struct tmln {
int32 rxbpr; /* rcv buf remove */ int32 rxbpr; /* rcv buf remove */
int32 rxbpi; /* rcv buf insert */ int32 rxbpi; /* rcv buf insert */
int32 rxcnt; /* rcv count */ int32 rxcnt; /* rcv count */
int32 rxpcnt; /* rcv packet count */
int32 txbpr; /* xmt buf remove */ int32 txbpr; /* xmt buf remove */
int32 txbpi; /* xmt buf insert */ int32 txbpi; /* xmt buf insert */
int32 txcnt; /* xmt count */ int32 txcnt; /* xmt count */
int32 txpcnt; /* xmt packet count */
int32 txdrp; /* xmt drop count */ int32 txdrp; /* xmt drop count */
int32 txbsz; /* xmt buffer size */ int32 txbsz; /* xmt buffer size */
int32 txbfd; /* xmt buffered flag */ int32 txbfd; /* xmt buffered flag */
@@ -125,6 +129,13 @@ struct tmln {
char rxb[TMXR_MAXBUF]; /* rcv buffer */ char rxb[TMXR_MAXBUF]; /* rcv buffer */
char rbr[TMXR_MAXBUF]; /* rcv break */ char rbr[TMXR_MAXBUF]; /* rcv break */
char *txb; /* xmt buffer */ 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 */ TMXR *mp; /* back pointer to mux */
char *serconfig; /* line config */ char *serconfig; /* line config */
SERHANDLE serport; /* serial port handle */ 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_reset_ln (TMLN *lp);
t_stat tmxr_detach_ln (TMLN *lp); t_stat tmxr_detach_ln (TMLN *lp);
int32 tmxr_getc_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); void tmxr_poll_rx (TMXR *mp);
t_stat tmxr_putc_ln (TMLN *lp, int32 chr); 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); void tmxr_poll_tx (TMXR *mp);
int32 tmxr_send_buffered_data (TMLN *lp); int32 tmxr_send_buffered_data (TMLN *lp);
t_stat tmxr_open_master (TMXR *mp, char *cptr); 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); t_stat tmxr_dscln (UNIT *uptr, int32 val, char *cptr, void *desc);
int32 tmxr_rqln (TMLN *lp); int32 tmxr_rqln (TMLN *lp);
int32 tmxr_tqln (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_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_lnorder (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat tmxr_show_summ (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat tmxr_show_summ (FILE *st, UNIT *uptr, int32 val, void *desc);