diff --git a/scp.c b/scp.c index 9f1729a5..12f209d4 100644 --- a/scp.c +++ b/scp.c @@ -1381,7 +1381,7 @@ static const char simh_help[] = "+sh{ow} {arg,...} show unit parameters\n" "+sh{ow} ethernet show ethernet devices\n" "+sh{ow} serial show serial devices\n" - "+sh{ow} multiplexer show open multiplexer devices\n" + "+sh{ow} multiplexer {dev} show open multiplexer device info\n" #if defined(USE_SIM_VIDEO) "+sh{ow} video show video capabilities\n" #endif diff --git a/sim_tmxr.c b/sim_tmxr.c index e583a694..3d974e67 100644 --- a/sim_tmxr.c +++ b/sim_tmxr.c @@ -872,6 +872,8 @@ if (mp->port) /* copy port */ sprintf (growstring(&tptr, 13 + strlen (mp->port)), "%s%s", mp->port, mp->notelnet ? ";notelnet" : ""); if (mp->logfiletmpl[0]) /* logfile info */ sprintf (growstring(&tptr, 7 + strlen (mp->logfiletmpl)), ",Log=%s", mp->logfiletmpl); +if (mp->buffered) + sprintf (growstring(&tptr, 10 + 10), ",Buffered=%d", mp->buffered); while ((*tptr == ',') || (*tptr == ' ')) memmove (tptr, tptr+1, strlen(tptr+1)+1); for (i=0; ilines; ++i) { @@ -2483,21 +2485,25 @@ t_stat tmxr_set_line_speed (TMLN *lp, CONST char *speed) UNIT *uptr; CONST char *cptr; t_stat r; +uint32 rxbps; if (!speed || !*speed) return SCPE_2FARG; if (_tmln_speed_delta (speed) < 0) return SCPE_ARG; -lp->rxbps = (uint32)strtotv (speed, &cptr, 10); +rxbps = (uint32)strtotv (speed, &cptr, 10); if (*cptr == '*') { uint32 bpsfactor = (uint32) get_uint (cptr+1, 10, 32, &r); if (r != SCPE_OK) return r; lp->bpsfactor = bpsfactor; + if (speed == cptr) /* just changing bps factor? */ + return SCPE_OK; /* Done now */ } +lp->rxbps = rxbps; /* use supplied speed */ if ((lp->serport) && (lp->bpsfactor != 0.0)) - lp->bpsfactor = 1.0; + lp->bpsfactor = 1.0; /* Ignore bps factor for serial ports */ lp->rxdeltausecs = (uint32)(_tmln_speed_delta (speed) / lp->bpsfactor); lp->rxnexttime = 0.0; uptr = lp->uptr; @@ -3073,6 +3079,8 @@ t_stat tmxr_set_line_unit (TMXR *mp, int line, UNIT *uptr_poll) { if ((line < 0) || (line >= mp->lines)) return SCPE_ARG; +if (mp->ldsc[line].uptr) + mp->ldsc[line].uptr->dynflags &= ~UNIT_TM_POLL; mp->ldsc[line].uptr = uptr_poll; return SCPE_OK; } @@ -3104,6 +3112,8 @@ t_stat tmxr_set_line_output_unit (TMXR *mp, int line, UNIT *uptr_poll) { if ((line < 0) || (line >= mp->lines)) return SCPE_ARG; +if (mp->ldsc[line].o_uptr) + mp->ldsc[line].o_uptr->dynflags &= ~UNIT_TM_POLL; mp->ldsc[line].o_uptr = uptr_poll; return SCPE_OK; } @@ -3857,11 +3867,14 @@ int32 i; if (mp->dptr == NULL) /* has device been set? */ mp->dptr = find_dev_from_unit (uptr); /* no, so set device now */ -mp->uptr = uptr; /* save unit for polling */ +if (mp->uptr == NULL) /* has polling unit been set? */ + mp->uptr = uptr; /* save unit for polling */ r = tmxr_open_master (mp, cptr); /* open master socket */ if (r != SCPE_OK) /* error? */ return r; uptr->filename = tmxr_mux_attach_string (uptr->filename, mp);/* save */ +if (uptr->filename == NULL) /* avoid dangling NULL pointer */ + uptr->filename = (char *)calloc (1, 1); /* provide an emptry string */ uptr->flags = uptr->flags | UNIT_ATT; /* no more errors */ uptr->tmxr = (void *)mp; if ((mp->lines > 1) || @@ -3910,105 +3923,128 @@ if (tmxr_open_device_count) return SCPE_OK; } -t_stat tmxr_show_open_devices (FILE* st, DEVICE *dptr, UNIT* uptr, int32 val, CONST char* desc) -{ -int i, j; -if (0 == tmxr_open_device_count) +t_stat tmxr_show_open_device (FILE* st, TMXR *mp) +{ +int j; +TMLN *lp; +UNIT *o_uptr = mp->ldsc[0].o_uptr; +UNIT *uptr = mp->ldsc[0].uptr; +char *attach; + +fprintf(st, "Multiplexer device: %s", (mp->dptr ? sim_dname (mp->dptr) : "")); +if (mp->lines > 1) { + fprintf(st, ", "); + tmxr_show_lines(st, NULL, 0, mp); + } +if (mp->packet) + fprintf(st, ", Packet"); +if (mp->datagram) + fprintf(st, ", UDP"); +if (mp->notelnet) + fprintf(st, ", Telnet=disabled"); +if (mp->modem_control) + fprintf(st, ", ModemControl=enabled"); +if (mp->buffered) + fprintf(st, ", Buffered=%d", mp->buffered); +for (j = 1; j < mp->lines; j++) + if (o_uptr != mp->ldsc[j].o_uptr) + break; +if (j == mp->lines) + fprintf(st, ", Output Unit: %s", sim_uname (o_uptr)); +for (j = 1; j < mp->lines; j++) + if (uptr != mp->ldsc[j].uptr) + break; +if (j == mp->lines) { + fprintf(st, ",\n Input Polling Unit: %s", sim_uname (uptr)); + if (uptr != mp->uptr) + fprintf(st, ", Connection Polling Unit: %s", sim_uname (mp->uptr)); + } +attach = tmxr_mux_attach_string (NULL, mp); +if (attach) + fprintf(st, ",\n attached to %s, ", attach); +free (attach); +tmxr_show_summ(st, NULL, 0, mp); +fprintf(st, ", sessions=%d", mp->sessions); +if (mp->lines == 1) { + if (mp->ldsc->rxbps) { + fprintf(st, ", Speed=%d", mp->ldsc->rxbps); + if (mp->ldsc->bpsfactor != 1.0) + fprintf(st, "*%.0f", mp->ldsc->bpsfactor); + fprintf(st, " bps"); + } + } +fprintf(st, "\n"); +if (mp->ring_start_time) { + fprintf (st, " incoming Connection from: %s ringing for %d milliseconds\n", mp->ring_ipad, sim_os_msec () - mp->ring_start_time); + } +for (j = 0; j < mp->lines; j++) { + lp = mp->ldsc + j; + if (mp->lines > 1) { + if (lp->dptr && (mp->dptr != lp->dptr)) + fprintf (st, "Device: %s ", sim_dname(lp->dptr)); + fprintf (st, "Line: %d", j); + if (lp->conn == TMXR_LINE_DISABLED) + fprintf (st, " - Disabled"); + if (mp->notelnet != lp->notelnet) + fprintf (st, " - %stelnet", lp->notelnet ? "no" : ""); + if (lp->uptr && (lp->uptr != lp->mp->uptr)) + fprintf (st, " - Unit: %s", sim_uname (lp->uptr)); + if ((lp->o_uptr != o_uptr) && lp->o_uptr && (lp->o_uptr != lp->mp->uptr) && (lp->o_uptr != lp->uptr)) + fprintf (st, " - Output Unit: %s", sim_uname (lp->o_uptr)); + if (mp->modem_control != lp->modem_control) + fprintf(st, ", ModemControl=%s", lp->modem_control ? "enabled" : "disabled"); + if (lp->loopback) + fprintf(st, ", Loopback"); + if (lp->rxbps) { + fprintf(st, ", Speed=%d", lp->rxbps); + if (lp->bpsfactor != 1.0) + fprintf(st, "*%.0f", lp->bpsfactor); + fprintf(st, " bps"); + } + else { + if (lp->bpsfactor != 1.0) + fprintf(st, ", Speed=*%.0f bps", lp->bpsfactor); + } + fprintf (st, "\n"); + } + if ((!lp->sock) && (!lp->connecting) && (!lp->serport) && (!lp->master)) { + if ((lp->modem_control) || (lp->txbfd)) + tmxr_fconns (st, lp, -1); + continue; + } + tmxr_fconns (st, lp, -1); + tmxr_fstats (st, lp, -1); + } +return SCPE_OK; +} + + +t_stat tmxr_show_open_devices (FILE* st, DEVICE *dptr, UNIT* uptr, int32 val, CONST char* cptr) +{ +int i; +char gbuf[CBUFSIZE]; + +cptr = get_glyph (cptr, gbuf, 0); +if (*cptr) + return SCPE_2MARG; +if ((0 == tmxr_open_device_count) && + (gbuf[0] == '\0')) fprintf(st, "No Attached Multiplexer Devices\n"); else { for (i=0; ildsc[0].o_uptr; - UNIT *uptr = mp->ldsc[0].uptr; - char *attach; - fprintf(st, "Multiplexer device: %s", (mp->dptr ? sim_dname (mp->dptr) : "")); - if (mp->lines > 1) { - fprintf(st, ", "); - tmxr_show_lines(st, NULL, 0, mp); - } - if (mp->packet) - fprintf(st, ", Packet"); - if (mp->datagram) - fprintf(st, ", UDP"); - if (mp->notelnet) - fprintf(st, ", Telnet=disabled"); - if (mp->modem_control) - fprintf(st, ", ModemControl=enabled"); - if (mp->buffered) - fprintf(st, ", Buffered=%d", mp->buffered); - for (j = 1; j < mp->lines; j++) - if (o_uptr != mp->ldsc[j].o_uptr) + if ((gbuf[0] == '\0') || + (0 == strcmp (gbuf, mp->dptr->name))) { + tmxr_show_open_device (st, mp); + if (gbuf[0] != '\0') break; - if (j == mp->lines) - fprintf(st, ", Output Unit: %s", sim_uname (o_uptr)); - for (j = 1; j < mp->lines; j++) - if (uptr != mp->ldsc[j].uptr) - break; - if (j == mp->lines) { - fprintf(st, ",\n Input Polling Unit: %s", sim_uname (uptr)); - if (uptr != mp->uptr) - fprintf(st, ", Connection Polling Unit: %s", sim_uname (mp->uptr)); - } - attach = tmxr_mux_attach_string (NULL, mp); - if (attach) - fprintf(st, ",\n attached to %s, ", attach); - free (attach); - tmxr_show_summ(st, NULL, 0, mp); - fprintf(st, ", sessions=%d", mp->sessions); - if (mp->lines == 1) { - if (mp->ldsc->rxbps) { - fprintf(st, ", Speed=%d", mp->ldsc->rxbps); - if (mp->ldsc->bpsfactor != 1.0) - fprintf(st, "*%.0f", mp->ldsc->bpsfactor); - fprintf(st, " bps"); - } - } - fprintf(st, "\n"); - if (mp->ring_start_time) { - fprintf (st, " incoming Connection from: %s ringing for %d milliseconds\n", mp->ring_ipad, sim_os_msec () - mp->ring_start_time); - } - for (j = 0; j < mp->lines; j++) { - lp = mp->ldsc + j; - if (mp->lines > 1) { - if (lp->dptr && (mp->dptr != lp->dptr)) - fprintf (st, "Device: %s ", sim_dname(lp->dptr)); - fprintf (st, "Line: %d", j); - if (lp->conn == TMXR_LINE_DISABLED) - fprintf (st, " - Disabled"); - if (mp->notelnet != lp->notelnet) - fprintf (st, " - %stelnet", lp->notelnet ? "no" : ""); - if (lp->uptr && (lp->uptr != lp->mp->uptr)) - fprintf (st, " - Unit: %s", sim_uname (lp->uptr)); - if ((lp->o_uptr != o_uptr) && lp->o_uptr && (lp->o_uptr != lp->mp->uptr) && (lp->o_uptr != lp->uptr)) - fprintf (st, " - Output Unit: %s", sim_uname (lp->o_uptr)); - if (mp->modem_control != lp->modem_control) - fprintf(st, ", ModemControl=%s", lp->modem_control ? "enabled" : "disabled"); - if (lp->loopback) - fprintf(st, ", Loopback"); - if (lp->rxbps) { - fprintf(st, ", Speed=%d", lp->rxbps); - if (lp->bpsfactor != 1.0) - fprintf(st, "*%.0f", lp->bpsfactor); - fprintf(st, " bps"); - } - else { - if (lp->bpsfactor != 1.0) - fprintf(st, ", Speed=*%.0f bps", lp->bpsfactor); - } - fprintf (st, "\n"); - } - if ((!lp->sock) && (!lp->connecting) && (!lp->serport) && (!lp->master)) { - if ((lp->modem_control) || (lp->txbfd)) - tmxr_fconns (st, lp, -1); - continue; - } - tmxr_fconns (st, lp, -1); - tmxr_fstats (st, lp, -1); } } + if ((gbuf[0] != '\0') && + (i == tmxr_open_device_count)) + return sim_messagef (SCPE_ARG, "Multiplexer device %s not found or attached\n", gbuf); } return SCPE_OK; } @@ -4146,13 +4182,17 @@ for (i=0; ilines; i++) { if ((lp->conn || lp->txbfd) && /* Connected (or buffered)? */ (uptr == lp->o_uptr) && /* output completion unit? */ (lp->txbps)) { /* while rate limiting */ - if ((tmxr_tqln(lp)) && /* pending output data? */ - (lp->txnexttime < sim_gtime_now)) + if ((tmxr_tqln(lp)) && /* pending output data */ + (lp->txnexttime < sim_gtime_now))/* that can be transmitted now? */ tmxr_send_buffered_data (lp);/* flush it */ - if (lp->txnexttime > sim_gtime_now) - due = (int32)(lp->txnexttime - sim_gtime_now); - else - due = sim_processing_event ? 1 : 0; /* avoid potential infinite loop if called from service routine */ + if (tmxr_tqln(lp) == 0) /* no pending output data */ + due = interval; /* No rush */ + else { + if (lp->txnexttime > sim_gtime_now) + due = (int32)(lp->txnexttime - sim_gtime_now); + else + due = sim_processing_event ? 1 : 0; /* avoid potential infinite loop if called from service routine */ + } sooner = MIN(sooner, due); } }