/*
 * tstcom2.c  31 Oct 83  Craig Milo Rogers at USC/ISI
 *
 *	This program tests the COM: communications package
 * by using it as a TTY Telnet box.  Both COM: ports are used
 * for a single connection.  COM1: is the user port, and COM2:
 * is the server port.
 */

#define M_TSTCOM

#include "stdio.h"

#include "truth.h"
#include "beauty.h"

#define TNESCAPE 0036		/* "Telnet" escape char:  control-uparrow. */

#define RBUFLEN 4096		/* Receive buffer length. */
#define TBUFLEN 512		/* Transmit buffer length. */
static char rbuf1[RBUFLEN];	/* Receive data buffer. */
static char tbuf1[TBUFLEN];	/* Transmit data buffer. */
static char rbuf2[RBUFLEN];	/* Receive data buffer. */
static char tbuf2[TBUFLEN];	/* Transmit data buffer. */

main(argc,argv)
int argc;			/* Number of arguments. */
char *argv[];			/* Pointers to argument strings. */
{
    int rate;			/* Baud rate in bps. */
    int divisor;		/* Baud rage generator divisor. */
      int c;			/* Holds a data character. */
    bool sawesc;		/* Indicates that ctrl-q was last char. */
    bool running;		/* FALSE indicates exit request. */
    int i;			/* Counter. */
    int unit;			/* COM: unit number. */

    if (argc < 2) {		/* Not enough args, give help message. */
	fprintf(stderr, "usage:  tstcom2 baudrate\n");
	exit(1);
    }

    rate = 0;
    sscanf(argv[1], "%d", &rate);
    if ((divisor = getdivisor(rate)) == 0) {
	fprintf(stderr, "tstcom2: Unrecognized baud rate.\n");
	exit(1);
    }

				/* Initialize COM1: and COM2:. */
    int_ini();			/* Start with interrupt package. */
    com_ini(1, divisor, tbuf1, TBUFLEN, rbuf1, RBUFLEN);
    com_ini(2, divisor, tbuf2, TBUFLEN, rbuf2, RBUFLEN);

    sawesc = FALSE;		/* Start off with normal data. */
    running = TRUE;		/* Running the glass tty. */
    unit = 2;			/* Destination is COM2:. */

    while (running) {		/* Until we decide to exit: */
	if (com_icnt(1) != 0) {	/* Got a character? */
	    c = com_getc(1);	/* Pick up the character. */
	    if (sawesc) {	/* Did we just see a telnet escape? */
		sawesc = FALSE;	/* Cancel the saw-escape flag. */
		switch (c &0177) {	/* Dispatch to command processor. */

		case TNESCAPE:	/* A second escape char. */
		    com_putc(unit, c);	/* Pass it through. */
		    break;

		case 'b':	/* A request to send BREAK. */
		case 'B':
		    com_break(unit);
		    break;

		case 'c':	/* The "close" command. */
		case 'C':
		case 'e':	/* The "exit" command. */
		case 'E':
		case 'q':	/* The "quit" command. */
		case 'Q':
		    running = FALSE;
		    continue;

		default:	/* Complain about bad char. */
		    com_putc(1, 0007);	/* Ring the "bell". */
		    break;
		}
	    } else {		/* Otherwise, didn't see escape prev. */
		switch (c &0177) {	/* Dispatch to character processor. */

		case TNESCAPE:		/* Process "Telnet" escape char. */
		    sawesc = TRUE;	/* Set saw-escape flag. */
		    break;

		default:		/* Otherwise, send to COM1: as is. */
		    com_putc(unit, c);	/* Ignore errors. */
		}
	    }
	}
	for (i = com_icnt(unit); i > 0; i--) {
	    c = com_getc(unit);	/* Get a COM2: character. */
	    com_putc(1, c);	/* Send to COM1:. */
	}
    }

    com_trm(1);			/* Restore interrupt vectors, etc. */
    com_trm(2);
    int_trm();
}

int				/* Returns baud rate generator divisor. */
getdivisor(rate)		/* Convert baud rate to BRG divisor. */
int rate;			/* Baud rate. */
{
    switch (rate) {		/* Dispatch on baud rate. */
    case 9600:	return (12);
    case 4800:	return (24);
    case 2400:	return (48);
    case 1200:	return (96);
    case 300:	return (384);
    default:	return (0);	/* Unrecognized rate. */
    }
}
