SCP: Added EXPECT and SEND commands to react to data from and inject data into the simulated console port (and other MUX ports)
Ideas based on Dave Bryan's console halt efforts. sim> SEND {<mux>:line} {DELAY=n,}"string" Where <mux> is the name of the device pointed to by the TMXR structure. If <mux>:line isn't specified, then the console device is implicitly being referenced. Delay is optional and once set persists for subsequent SEND operations to the same device. Delay defaults to 1000. The DELAY value is a minimum number of instructions which must execute before the next character in the provided string will be injected to the console port. The DELAY value has effect between the characters delivered as well. "string" requires quotes and within the quoted string, common C escape character syntax is available (\r\r\t, etc.). Each device (console, and each line in each mux) has a separate value for DELAY. An arbitrary number of 'expect' conditions can be defined. The command syntax is: sim> EXPECT {<mux>:line} {[cnt]} "matchstring" {actioncommand {; actioncommand ...}} Where <mux> is the name of the device pointed to by the TMXR structure. If <mux>:line isn't specified, then the console device is implicitly being referenced. "matchstring" requires quotes and within the quoted string, common C escape character syntax is available (\r\r\t, etc.). The quotes used can be single or double quotes, but the closing quote must match the opening quote. The match string might be extended to allow the use of perl style regular expressions in the "matchstring" when a -R switch is specified on the command line. sim> EXPECT "Enter Color: " SEND "Red\r"; g A specific 'expect' condition can be removed with: sim> NOEXPECT {<mux>:line} "matchstring" All 'expect' conditions can be removed with: sim> NOEXPECT {<mux>:line} 'expect' conditions can be examined with: sim> SHOW EXPECT {<mux>:line} Expect rules are one-shots (i.e. they disappear once a match has occurred) unless they are explicitly described as persistent with the -P switch. The -C switch is available when defining expect rules. The effect of a rule defined with the -C flag is that when an expect match occurs for that rule, ALL rules are cleared for that device (console or <mux>:line).
This commit is contained in:
parent
d0865d37f5
commit
02e90de6a4
7 changed files with 1030 additions and 62 deletions
18
scp.h
18
scp.h
|
@ -82,6 +82,8 @@ t_stat call_cmd (int32 flag, char *ptr);
|
||||||
t_stat on_cmd (int32 flag, char *ptr);
|
t_stat on_cmd (int32 flag, char *ptr);
|
||||||
t_stat noop_cmd (int32 flag, char *ptr);
|
t_stat noop_cmd (int32 flag, char *ptr);
|
||||||
t_stat assert_cmd (int32 flag, char *ptr);
|
t_stat assert_cmd (int32 flag, char *ptr);
|
||||||
|
t_stat send_cmd (int32 flag, char *ptr);
|
||||||
|
t_stat expect_cmd (int32 flag, char *ptr);
|
||||||
t_stat help_cmd (int32 flag, char *ptr);
|
t_stat help_cmd (int32 flag, char *ptr);
|
||||||
t_stat spawn_cmd (int32 flag, char *ptr);
|
t_stat spawn_cmd (int32 flag, char *ptr);
|
||||||
t_stat echo_cmd (int32 flag, char *ptr);
|
t_stat echo_cmd (int32 flag, char *ptr);
|
||||||
|
@ -114,9 +116,12 @@ char *get_sim_opt (int32 opt, char *cptr, t_stat *st);
|
||||||
char *get_glyph (const char *iptr, char *optr, char mchar);
|
char *get_glyph (const char *iptr, char *optr, char mchar);
|
||||||
char *get_glyph_nc (const char *iptr, char *optr, char mchar);
|
char *get_glyph_nc (const char *iptr, char *optr, char mchar);
|
||||||
char *get_glyph_quoted (const char *iptr, char *optr, char mchar);
|
char *get_glyph_quoted (const char *iptr, char *optr, char mchar);
|
||||||
t_value get_uint (char *cptr, uint32 radix, t_value max, t_stat *status);
|
t_value get_uint (const char *cptr, uint32 radix, t_value max, t_stat *status);
|
||||||
char *get_range (DEVICE *dptr, char *cptr, t_addr *lo, t_addr *hi,
|
char *get_range (DEVICE *dptr, char *cptr, t_addr *lo, t_addr *hi,
|
||||||
uint32 rdx, t_addr max, char term);
|
uint32 rdx, t_addr max, char term);
|
||||||
|
t_stat sim_decode_quoted_string (const char *iptr, uint8 *optr, uint32 *osize);
|
||||||
|
char *sim_encode_quoted_string (const uint8 *iptr, uint32 size);
|
||||||
|
void fprint_buffer_string (FILE *st, const uint8 *buf, uint32 size);
|
||||||
t_value strtotv (const char *cptr, char **endptr, uint32 radix);
|
t_value strtotv (const char *cptr, char **endptr, uint32 radix);
|
||||||
t_stat fprint_val (FILE *stream, t_value val, uint32 rdx, uint32 wid, uint32 fmt);
|
t_stat fprint_val (FILE *stream, t_value val, uint32 rdx, uint32 wid, uint32 fmt);
|
||||||
t_stat sim_print_val (t_value val, uint32 radix, uint32 width, uint32 format);
|
t_stat sim_print_val (t_value val, uint32 radix, uint32 width, uint32 format);
|
||||||
|
@ -140,6 +145,17 @@ uint32 sim_brk_test (t_addr bloc, uint32 btyp);
|
||||||
void sim_brk_clrspc (uint32 spc);
|
void sim_brk_clrspc (uint32 spc);
|
||||||
char *sim_brk_clract (void);
|
char *sim_brk_clract (void);
|
||||||
void sim_brk_setact (const char *action);
|
void sim_brk_setact (const char *action);
|
||||||
|
t_stat sim_send_input (SEND *snd, uint8 *data, size_t size, uint32 delay);
|
||||||
|
t_stat sim_show_send_input (FILE *st, SEND *snd);
|
||||||
|
t_bool sim_send_poll_data (SEND *snd, t_stat *stat);
|
||||||
|
t_stat sim_set_expect (EXPECT *exp, char *cptr);
|
||||||
|
t_stat sim_set_noexpect (EXPECT *exp, char *cptr);
|
||||||
|
t_stat sim_exp_set (EXPECT *exp, const char *match, int32 cnt, int32 switches, char *act);
|
||||||
|
t_stat sim_exp_clr (EXPECT *exp, const char *match);
|
||||||
|
t_stat sim_exp_clrall (EXPECT *exp);
|
||||||
|
t_stat sim_exp_show (FILE *st, EXPECT *exp, const char *match);
|
||||||
|
t_stat sim_exp_showall (FILE *st, EXPECT *exp);
|
||||||
|
t_stat sim_exp_check (EXPECT *exp, uint8 data);
|
||||||
char *match_ext (char *fnam, char *ext);
|
char *match_ext (char *fnam, char *ext);
|
||||||
t_stat show_version (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
t_stat show_version (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||||
t_stat set_dev_debug (DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
t_stat set_dev_debug (DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||||
|
|
|
@ -103,7 +103,10 @@
|
||||||
sim_show_cons_log show console log
|
sim_show_cons_log show console log
|
||||||
sim_tt_inpcvt convert input character per mode
|
sim_tt_inpcvt convert input character per mode
|
||||||
sim_tt_outcvt convert output character per mode
|
sim_tt_outcvt convert output character per mode
|
||||||
|
sim_cons_get_send get console send structure address
|
||||||
|
sim_cons_get_expect get console expect structure address
|
||||||
|
sim_show_cons_send_input show pending input data
|
||||||
|
sim_show_cons_expect show expect rules and state
|
||||||
sim_ttinit called once to get initial terminal state
|
sim_ttinit called once to get initial terminal state
|
||||||
sim_ttrun called to put terminal into run state
|
sim_ttrun called to put terminal into run state
|
||||||
sim_ttcmd called to return terminal to command state
|
sim_ttcmd called to return terminal to command state
|
||||||
|
@ -160,6 +163,9 @@ int32 sim_del_char = '\b'; /* delete character */
|
||||||
#else
|
#else
|
||||||
int32 sim_del_char = 0177;
|
int32 sim_del_char = 0177;
|
||||||
#endif
|
#endif
|
||||||
|
SEND sim_con_send = {SEND_DEFAULT_DELAY};
|
||||||
|
EXPECT sim_con_expect;
|
||||||
|
|
||||||
static t_stat sim_con_poll_svc (UNIT *uptr); /* console connection poll routine */
|
static t_stat sim_con_poll_svc (UNIT *uptr); /* console connection poll routine */
|
||||||
static t_stat sim_con_reset (DEVICE *dptr); /* console reset routine */
|
static t_stat sim_con_reset (DEVICE *dptr); /* console reset routine */
|
||||||
UNIT sim_con_unit = { UDATA (&sim_con_poll_svc, 0, 0) }; /* console connection unit */
|
UNIT sim_con_unit = { UDATA (&sim_con_poll_svc, 0, 0) }; /* console connection unit */
|
||||||
|
@ -247,6 +253,8 @@ static SHTAB show_con_tab[] = {
|
||||||
{ "TELNET", &sim_show_telnet, 0 },
|
{ "TELNET", &sim_show_telnet, 0 },
|
||||||
{ "DEBUG", &sim_show_cons_debug, 0 },
|
{ "DEBUG", &sim_show_cons_debug, 0 },
|
||||||
{ "BUFFERED", &sim_show_cons_buff, 0 },
|
{ "BUFFERED", &sim_show_cons_buff, 0 },
|
||||||
|
{ "EXPECT", &sim_show_cons_expect, 0 },
|
||||||
|
{ "INPUT", &sim_show_cons_send_input, 0 },
|
||||||
{ NULL, NULL, 0 }
|
{ NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1369,6 +1377,13 @@ if (sim_con_ldsc.serport == 0) /* ignore if already closed */
|
||||||
return tmxr_close_master (&sim_con_tmxr); /* close master socket */
|
return tmxr_close_master (&sim_con_tmxr); /* close master socket */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Show the console expect rules and state */
|
||||||
|
|
||||||
|
t_stat sim_show_cons_expect (FILE *st, DEVICE *dunused, UNIT *uunused, int32 flag, char *cptr)
|
||||||
|
{
|
||||||
|
return sim_exp_show (st, &sim_con_expect, cptr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Log File Open/Close/Show Support */
|
/* Log File Open/Close/Show Support */
|
||||||
|
|
||||||
/* Open log file */
|
/* Open log file */
|
||||||
|
@ -1511,12 +1526,35 @@ for (i = 0; i < sec; i++) { /* loop */
|
||||||
return SCPE_TTMO; /* timed out */
|
return SCPE_TTMO; /* timed out */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get Send object address for console */
|
||||||
|
|
||||||
|
SEND *sim_cons_get_send (void)
|
||||||
|
{
|
||||||
|
return &sim_con_send;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Expect object address for console */
|
||||||
|
|
||||||
|
EXPECT *sim_cons_get_expect (void)
|
||||||
|
{
|
||||||
|
return &sim_con_expect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Display console Queued input data status */
|
||||||
|
|
||||||
|
t_stat sim_show_cons_send_input (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
|
||||||
|
{
|
||||||
|
return sim_show_send_input (st, &sim_con_send);
|
||||||
|
}
|
||||||
|
|
||||||
/* Poll for character */
|
/* Poll for character */
|
||||||
|
|
||||||
t_stat sim_poll_kbd (void)
|
t_stat sim_poll_kbd (void)
|
||||||
{
|
{
|
||||||
int32 c;
|
int32 c;
|
||||||
|
|
||||||
|
if (sim_send_poll_data (&sim_con_send, &c)) /* injected input characters available? */
|
||||||
|
return c;
|
||||||
c = sim_os_poll_kbd (); /* get character */
|
c = sim_os_poll_kbd (); /* get character */
|
||||||
if ((c == SCPE_STOP) || /* ^E or not Telnet? */
|
if ((c == SCPE_STOP) || /* ^E or not Telnet? */
|
||||||
((sim_con_tmxr.master == 0) && /* and not serial? */
|
((sim_con_tmxr.master == 0) && /* and not serial? */
|
||||||
|
@ -1540,6 +1578,7 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat sim_putchar (int32 c)
|
t_stat sim_putchar (int32 c)
|
||||||
{
|
{
|
||||||
|
sim_exp_check (&sim_con_expect, c);
|
||||||
if ((sim_con_tmxr.master == 0) && /* not Telnet? */
|
if ((sim_con_tmxr.master == 0) && /* not Telnet? */
|
||||||
(sim_con_ldsc.serport == 0)) { /* and not serial port */
|
(sim_con_ldsc.serport == 0)) { /* and not serial port */
|
||||||
if (sim_log) /* log file? */
|
if (sim_log) /* log file? */
|
||||||
|
@ -1563,6 +1602,7 @@ t_stat sim_putchar_s (int32 c)
|
||||||
{
|
{
|
||||||
t_stat r;
|
t_stat r;
|
||||||
|
|
||||||
|
sim_exp_check (&sim_con_expect, c);
|
||||||
if ((sim_con_tmxr.master == 0) && /* not Telnet? */
|
if ((sim_con_tmxr.master == 0) && /* not Telnet? */
|
||||||
(sim_con_ldsc.serport == 0)) { /* and not serial port */
|
(sim_con_ldsc.serport == 0)) { /* and not serial port */
|
||||||
if (sim_log) /* log file? */
|
if (sim_log) /* log file? */
|
||||||
|
|
|
@ -68,6 +68,8 @@ t_stat sim_set_cons_unbuff (int32 flg, char *cptr);
|
||||||
t_stat sim_set_cons_log (int32 flg, char *cptr);
|
t_stat sim_set_cons_log (int32 flg, char *cptr);
|
||||||
t_stat sim_set_cons_nolog (int32 flg, char *cptr);
|
t_stat sim_set_cons_nolog (int32 flg, char *cptr);
|
||||||
t_stat sim_set_deboff (int32 flag, char *cptr);
|
t_stat sim_set_deboff (int32 flag, char *cptr);
|
||||||
|
t_stat sim_set_cons_expect (int32 flg, char *cptr);
|
||||||
|
t_stat sim_set_cons_noexpect (int32 flg, char *cptr);
|
||||||
t_stat sim_debug_flush (void);
|
t_stat sim_debug_flush (void);
|
||||||
t_stat sim_set_pchar (int32 flag, char *cptr);
|
t_stat sim_set_pchar (int32 flag, char *cptr);
|
||||||
t_stat sim_show_console (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
t_stat sim_show_console (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||||
|
@ -80,10 +82,14 @@ t_stat sim_show_pchar (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cpt
|
||||||
t_stat sim_show_cons_buff (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
t_stat sim_show_cons_buff (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||||
t_stat sim_show_cons_log (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
t_stat sim_show_cons_log (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||||
t_stat sim_show_cons_debug (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
t_stat sim_show_cons_debug (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||||
|
t_stat sim_show_cons_expect (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||||
t_stat sim_check_console (int32 sec);
|
t_stat sim_check_console (int32 sec);
|
||||||
t_stat sim_open_logfile (char *filename, t_bool binary, FILE **pf, FILEREF **pref);
|
t_stat sim_open_logfile (char *filename, t_bool binary, FILE **pf, FILEREF **pref);
|
||||||
t_stat sim_close_logfile (FILEREF **pref);
|
t_stat sim_close_logfile (FILEREF **pref);
|
||||||
const char *sim_logfile_name (FILE *st, FILEREF *ref);
|
const char *sim_logfile_name (FILE *st, FILEREF *ref);
|
||||||
|
SEND *sim_cons_get_send (void);
|
||||||
|
EXPECT *sim_cons_get_expect (void);
|
||||||
|
t_stat sim_show_cons_send_input (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
|
||||||
t_stat sim_poll_kbd (void);
|
t_stat sim_poll_kbd (void);
|
||||||
t_stat sim_putchar (int32 c);
|
t_stat sim_putchar (int32 c);
|
||||||
t_stat sim_putchar_s (int32 c);
|
t_stat sim_putchar_s (int32 c);
|
||||||
|
|
40
sim_defs.h
40
sim_defs.h
|
@ -313,8 +313,9 @@ typedef uint32 t_addr;
|
||||||
#define SCPE_AFAIL (SCPE_BASE + 42) /* assert failed */
|
#define SCPE_AFAIL (SCPE_BASE + 42) /* assert failed */
|
||||||
#define SCPE_INVREM (SCPE_BASE + 43) /* invalid remote console command */
|
#define SCPE_INVREM (SCPE_BASE + 43) /* invalid remote console command */
|
||||||
#define SCPE_NOTATT (SCPE_BASE + 44) /* not attached */
|
#define SCPE_NOTATT (SCPE_BASE + 44) /* not attached */
|
||||||
|
#define SCPE_EXPECT (SCPE_BASE + 45) /* expect matched */
|
||||||
|
|
||||||
#define SCPE_MAX_ERR (SCPE_BASE + 45) /* Maximum SCPE Error Value */
|
#define SCPE_MAX_ERR (SCPE_BASE + 46) /* Maximum SCPE Error Value */
|
||||||
#define SCPE_KFLAG 0x1000 /* tti data flag */
|
#define SCPE_KFLAG 0x1000 /* tti data flag */
|
||||||
#define SCPE_BREAK 0x2000 /* tti break flag */
|
#define SCPE_BREAK 0x2000 /* tti break flag */
|
||||||
#define SCPE_NOMESSAGE 0x10000000 /* message display supression flag */
|
#define SCPE_NOMESSAGE 0x10000000 /* message display supression flag */
|
||||||
|
@ -632,6 +633,40 @@ struct sim_brktab {
|
||||||
char *act; /* action string */
|
char *act; /* action string */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Expect rule */
|
||||||
|
|
||||||
|
struct sim_exptab {
|
||||||
|
uint8 *match; /* match string */
|
||||||
|
uint32 size; /* match string size */
|
||||||
|
int32 cnt; /* proceed count */
|
||||||
|
int32 switches; /* flags */
|
||||||
|
#define EXP_TYP_PERSIST (SWMASK ('P')) /* rule persists after match, default is once a rule matches, it is removed */
|
||||||
|
#define EXP_TYP_CLEARALL (SWMASK ('C')) /* clear all rules after matching this rule, default is to once a rule matches, it is removed */
|
||||||
|
char *act; /* action string */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Expect Context */
|
||||||
|
|
||||||
|
struct sim_expect {
|
||||||
|
struct sim_exptab *rules; /* match rules */
|
||||||
|
int32 size; /* count of match rules */
|
||||||
|
uint8 *buf; /* buffer of output data which has produced */
|
||||||
|
uint32 buf_ins; /* buffer insertion point for the next output data */
|
||||||
|
uint32 buf_size; /* buffer size */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Send Context */
|
||||||
|
|
||||||
|
struct sim_send {
|
||||||
|
uint32 delay; /* instruction delay before/between sent data */
|
||||||
|
#define SEND_DEFAULT_DELAY 1000 /* default delay instruction count */
|
||||||
|
double next_time; /* execution time when next data can be sent */
|
||||||
|
uint8 *buffer; /* buffer */
|
||||||
|
size_t bufsize; /* buffer size */
|
||||||
|
int32 insoff; /* insert offset */
|
||||||
|
int32 extoff; /* extra offset */
|
||||||
|
};
|
||||||
|
|
||||||
/* Debug table */
|
/* Debug table */
|
||||||
|
|
||||||
struct sim_debtab {
|
struct sim_debtab {
|
||||||
|
@ -745,6 +780,9 @@ typedef struct sim_shtab SHTAB;
|
||||||
typedef struct sim_mtab MTAB;
|
typedef struct sim_mtab MTAB;
|
||||||
typedef struct sim_schtab SCHTAB;
|
typedef struct sim_schtab SCHTAB;
|
||||||
typedef struct sim_brktab BRKTAB;
|
typedef struct sim_brktab BRKTAB;
|
||||||
|
typedef struct sim_exptab EXPTAB;
|
||||||
|
typedef struct sim_expect EXPECT;
|
||||||
|
typedef struct sim_send SEND;
|
||||||
typedef struct sim_debtab DEBTAB;
|
typedef struct sim_debtab DEBTAB;
|
||||||
typedef struct sim_fileref FILEREF;
|
typedef struct sim_fileref FILEREF;
|
||||||
typedef struct sim_bitfield BITFIELD;
|
typedef struct sim_bitfield BITFIELD;
|
||||||
|
|
50
sim_tmxr.c
50
sim_tmxr.c
|
@ -1530,6 +1530,7 @@ uint32 tmp;
|
||||||
|
|
||||||
tmxr_debug_trace_line (lp, "tmxr_getc_ln()");
|
tmxr_debug_trace_line (lp, "tmxr_getc_ln()");
|
||||||
if (lp->conn && lp->rcve) { /* conn & enb? */
|
if (lp->conn && lp->rcve) { /* conn & enb? */
|
||||||
|
if (!sim_send_poll_data (&lp->send, &val)) { /* injected input characters available? */
|
||||||
j = lp->rxbpi - lp->rxbpr; /* # input chrs */
|
j = lp->rxbpi - lp->rxbpr; /* # input chrs */
|
||||||
if (j) { /* any? */
|
if (j) { /* any? */
|
||||||
tmp = lp->rxb[lp->rxbpr]; /* get char */
|
tmp = lp->rxb[lp->rxbpr]; /* get char */
|
||||||
|
@ -1540,6 +1541,7 @@ if (lp->conn && lp->rcve) { /* conn & enb? */
|
||||||
}
|
}
|
||||||
lp->rxbpr = lp->rxbpr + 1; /* adv pointer */
|
lp->rxbpr = lp->rxbpr + 1; /* adv pointer */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} /* end if conn */
|
} /* end if conn */
|
||||||
if (lp->rxbpi == lp->rxbpr) /* empty? zero ptrs */
|
if (lp->rxbpi == lp->rxbpr) /* empty? zero ptrs */
|
||||||
lp->rxbpi = lp->rxbpr = 0;
|
lp->rxbpi = lp->rxbpr = 0;
|
||||||
|
@ -1816,6 +1818,7 @@ if ((lp->txbfd && !lp->notelnet) || (TXBUF_AVAIL(lp) > 1)) {/* room for char (+
|
||||||
lp->xmte = 0; /* disable line */
|
lp->xmte = 0; /* disable line */
|
||||||
if (lp->txlog) /* log if available */
|
if (lp->txlog) /* log if available */
|
||||||
fputc (chr, lp->txlog);
|
fputc (chr, lp->txlog);
|
||||||
|
sim_exp_check (&lp->expect, chr); /* process expect rules as needed */
|
||||||
return SCPE_OK; /* char sent */
|
return SCPE_OK; /* char sent */
|
||||||
}
|
}
|
||||||
++lp->txdrp; lp->xmte = 0; /* no room, dsbl line */
|
++lp->txdrp; lp->xmte = 0; /* no room, dsbl line */
|
||||||
|
@ -3198,6 +3201,9 @@ for (i=0; i<tmxr_open_device_count; ++i)
|
||||||
if (!found) {
|
if (!found) {
|
||||||
tmxr_open_devices = (TMXR **)realloc(tmxr_open_devices, (tmxr_open_device_count+1)*sizeof(*tmxr_open_devices));
|
tmxr_open_devices = (TMXR **)realloc(tmxr_open_devices, (tmxr_open_device_count+1)*sizeof(*tmxr_open_devices));
|
||||||
tmxr_open_devices[tmxr_open_device_count++] = mux;
|
tmxr_open_devices[tmxr_open_device_count++] = mux;
|
||||||
|
for (i=0; i<mux->lines; i++)
|
||||||
|
if (0 == mux->ldsc[i].send.delay)
|
||||||
|
mux->ldsc[i].send.delay = SEND_DEFAULT_DELAY;
|
||||||
}
|
}
|
||||||
#if defined(SIM_ASYNCH_IO) && defined(SIM_ASYNCH_MUX)
|
#if defined(SIM_ASYNCH_IO) && defined(SIM_ASYNCH_MUX)
|
||||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||||
|
@ -3226,6 +3232,46 @@ pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static t_stat _tmxr_locate_line_send_expect (const char *cptr, SEND **snd, EXPECT **exp)
|
||||||
|
{
|
||||||
|
char gbuf[CBUFSIZE];
|
||||||
|
DEVICE *dptr;
|
||||||
|
int i;
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if (snd)
|
||||||
|
*snd = NULL;
|
||||||
|
if (exp)
|
||||||
|
*exp = NULL;
|
||||||
|
cptr = get_glyph(cptr, gbuf, ':');
|
||||||
|
dptr = find_dev (gbuf); /* device match? */
|
||||||
|
if (!dptr)
|
||||||
|
return SCPE_ARG;
|
||||||
|
|
||||||
|
for (i=0; i<tmxr_open_device_count; ++i)
|
||||||
|
if (tmxr_open_devices[i]->dptr == dptr) {
|
||||||
|
int line = (int)get_uint (cptr, 10, tmxr_open_devices[i]->lines, &r);
|
||||||
|
if (r != SCPE_OK)
|
||||||
|
return r;
|
||||||
|
if (snd)
|
||||||
|
*snd = &tmxr_open_devices[i]->ldsc[line].send;
|
||||||
|
if (exp)
|
||||||
|
*exp = &tmxr_open_devices[i]->ldsc[line].expect;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
return SCPE_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat tmxr_locate_line_send (const char *cptr, SEND **snd)
|
||||||
|
{
|
||||||
|
return _tmxr_locate_line_send_expect (cptr, snd, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat tmxr_locate_line_expect (const char *cptr, EXPECT **exp)
|
||||||
|
{
|
||||||
|
return _tmxr_locate_line_send_expect (cptr, NULL, exp);
|
||||||
|
}
|
||||||
|
|
||||||
t_stat tmxr_change_async (void)
|
t_stat tmxr_change_async (void)
|
||||||
{
|
{
|
||||||
#if defined(SIM_ASYNCH_IO)
|
#if defined(SIM_ASYNCH_IO)
|
||||||
|
@ -3812,6 +3858,10 @@ if (lp->modem_control) {
|
||||||
|
|
||||||
if ((lp->serport == 0) && (lp->sock) && (!lp->datagram))
|
if ((lp->serport == 0) && (lp->sock) && (!lp->datagram))
|
||||||
fprintf (st, " %s\n", (lp->notelnet) ? "Telnet disabled (RAW data)" : "Telnet protocol");
|
fprintf (st, " %s\n", (lp->notelnet) ? "Telnet disabled (RAW data)" : "Telnet protocol");
|
||||||
|
if (lp->send.buffer)
|
||||||
|
sim_show_send_input (st, &lp->send);
|
||||||
|
if (lp->expect.buf)
|
||||||
|
sim_exp_showall (st, &lp->expect);
|
||||||
if (lp->txlog)
|
if (lp->txlog)
|
||||||
fprintf (st, " Logging to %s\n", lp->txlogname);
|
fprintf (st, " Logging to %s\n", lp->txlogname);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -161,6 +161,8 @@ struct tmln {
|
||||||
UNIT *uptr; /* input polling unit (default to mp->uptr) */
|
UNIT *uptr; /* input polling unit (default to mp->uptr) */
|
||||||
UNIT *o_uptr; /* output polling unit (default to lp->uptr)*/
|
UNIT *o_uptr; /* output polling unit (default to lp->uptr)*/
|
||||||
DEVICE *dptr; /* line specific device */
|
DEVICE *dptr; /* line specific device */
|
||||||
|
EXPECT expect; /* Expect rules */
|
||||||
|
SEND send; /* Send input state */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tmxr {
|
struct tmxr {
|
||||||
|
@ -238,6 +240,8 @@ t_stat tmxr_activate (UNIT *uptr, int32 interval);
|
||||||
t_stat tmxr_activate_after (UNIT *uptr, int32 usecs_walltime);
|
t_stat tmxr_activate_after (UNIT *uptr, int32 usecs_walltime);
|
||||||
t_stat tmxr_clock_coschedule (UNIT *uptr, int32 interval);
|
t_stat tmxr_clock_coschedule (UNIT *uptr, int32 interval);
|
||||||
t_stat tmxr_change_async (void);
|
t_stat tmxr_change_async (void);
|
||||||
|
t_stat tmxr_locate_line_send (const char *dev_line, SEND **snd);
|
||||||
|
t_stat tmxr_locate_line_expect (const char *dev_line, EXPECT **exp);
|
||||||
t_stat tmxr_startup (void);
|
t_stat tmxr_startup (void);
|
||||||
t_stat tmxr_shutdown (void);
|
t_stat tmxr_shutdown (void);
|
||||||
t_stat tmxr_start_poll (void);
|
t_stat tmxr_start_poll (void);
|
||||||
|
|
Loading…
Add table
Reference in a new issue