[Date Prev] [Date Index] [Date Next] [Thread Prev] [Thread Index] [Thread Next]
Anton D. Kachalov mouse@yandex-team.ru
Mon, 21 Nov 2011 07:30:55 GMT
On 11/17/11 21:22, Joe Digilio wrote:
Hi all-
I'm a long time conserver user, and need to replace a failed Cyclades TS400.
The Moxa terminal servers were recommended to me by a colleague (who
does not use it with conserver). I'm wondering if anybody has
experience using them with conserver? I'll likely get the 6150 or
6250, since I only need a single port.We have bigger Moxas (16 port ones) and they work fine with Conserver.
I was also looking at the OpenGear ACM5002, if anybody wants to comment on that.We had some Moxa failure this year and no response from support, so we
--
had to throw them away. On the other hand we have very good contact with
OpenGear. So it's not surprise that I would personally choose OpenGear.
Thanks,
Wawrzek
Wawrzyniec (Wawrzek) Niewodniczański - 01223 435603 (35603) - wawrzekn
System Administrator - Engineering Services Team (XenServer)
Citrix Systems, Building 101, Cambridge Science Park, CB4 0FY, Cambridge
PhD in Quantum Chemistry, MSc in Molecular Engineering
_______________________________________________
users mailing list
users@conserver.com
https://www.conserver.com/mailman/listinfo/users
diff --git b/conserver/consent.c a/conserver/consent.c index aae6c26..59dfc89 100644 --- b/conserver/consent.c +++ a/conserver/consent.c @@ -744,6 +744,7 @@ ConsDown(pCE, downHard, force) { if (force != FLAGTRUE && !(FileBufEmpty(pCE->fdlog) && FileBufEmpty(pCE->cofile) && + /* FileBufEmpty(pCE->cocmd) && */ FileBufEmpty(pCE->initfile))) { pCE->ioState = ISFLUSHING; return; @@ -762,6 +763,12 @@ ConsDown(pCE, downHard, force) FD_CLR(cofile, &winit); FileClose(&pCE->cofile); } + if (pCE->cocmd != (CONSFILE *)0) { + int cofile = FileFDNum(pCE->cocmd); + FD_CLR(cofile, &rinit); + FD_CLR(cofile, &winit); + FileClose(&pCE->cocmd); + } if (pCE->fdlog != (CONSFILE *)0) { if (pCE->nolog) { TagLogfile(pCE, "Console logging restored"); @@ -799,6 +806,7 @@ ConsInit(pCE) time_t tyme; extern int FallBack PARAMS((char **, int *)); int cofile = -1; + int cocmd = -1; int ret; #if HAVE_GETTIMEOFDAY struct timeval tv; @@ -1129,6 +1137,147 @@ ipmi_sol_error: ipmi_intf_session_set_sol_escape_char(pCE->intf, SOL_ESCAPE_CHARACTER_DEFAULT); */ break; + + case REALCOM: + { + struct sockaddr_in port; + struct hostent *hp; +#if HAVE_SETSOCKOPT + int one = 1; +#endif + + usleep(100000); /* Not all terminal servers can keep up */ + + if ((hp = gethostbyname(pCE->host)) == NULL) { + Error("[%s] gethostbyname(%s): %s: forcing down", + pCE->server, pCE->host, hstrerror(h_errno)); + ConsDown(pCE, FLAGTRUE, FLAGTRUE); + return; + } +#if HAVE_MEMCPY + memcpy(&port.sin_addr.s_addr, hp->h_addr_list[0], + hp->h_length); +#else + bcopy(hp->h_addr_list[0], &port.sin_addr.s_addr, + hp->h_length); +#endif + port.sin_family = hp->h_addrtype; + port.sin_port = htons(pCE->netport+16); + + if ((cofile = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + Error + ("[%s] socket(AF_INET,SOCK_STREAM): %s: forcing down", + pCE->server, strerror(errno)); + ConsDown(pCE, FLAGTRUE, FLAGTRUE); + return; + } +#if HAVE_SETSOCKOPT + if (setsockopt + (cofile, SOL_SOCKET, SO_KEEPALIVE, (char *)&one, + sizeof(one)) < 0) { + Error + ("[%s] setsockopt(%u,SO_KEEPALIVE): %s: forcing down", + pCE->server, cofile, strerror(errno)); + ConsDown(pCE, FLAGTRUE, FLAGTRUE); + close(cofile); + return; + } +#endif + + if (!SetFlags(cofile, O_NONBLOCK, 0)) { + ConsDown(pCE, FLAGTRUE, FLAGTRUE); + close(cofile); + return; + } + + if ((ret = + connect(cofile, (struct sockaddr *)&port, + sizeof(port))) + < 0) { + if (errno != EINPROGRESS) { + Error("[%s] connect(%u): %s: forcing down", + pCE->server, cofile, strerror(errno)); + ConsDown(pCE, FLAGTRUE, FLAGTRUE); + close(cofile); + return; + } + } + if ((pCE->cocmd = + FileOpenFD(cofile, simpleSocket)) == (CONSFILE *)0) { + Error + ("[%s] FileOpenFD(%d,simpleSocket) failed: forcing down", + pCE->server, cofile); + ConsDown(pCE, FLAGTRUE, FLAGTRUE); + close(cofile); + return; + } + cocmd = cofile; + + /* Opening data connection */ + port.sin_port = htons(pCE->netport); + + if ((cofile = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + Error + ("[%s] socket(AF_INET,SOCK_STREAM): %s: forcing down", + pCE->server, strerror(errno)); + ConsDown(pCE, FLAGTRUE, FLAGTRUE); + return; + } +#if HAVE_SETSOCKOPT + if (setsockopt + (cofile, SOL_SOCKET, SO_KEEPALIVE, (char *)&one, + sizeof(one)) < 0) { + Error + ("[%s] setsockopt(%u,SO_KEEPALIVE): %s: forcing down", + pCE->server, cofile, strerror(errno)); + ConsDown(pCE, FLAGTRUE, FLAGTRUE); + close(cofile); + return; + } +#endif + + if (!SetFlags(cofile, O_NONBLOCK, 0)) { + ConsDown(pCE, FLAGTRUE, FLAGTRUE); + close(cofile); + return; + } + + if ((ret = + connect(cofile, (struct sockaddr *)&port, + sizeof(port))) + < 0) { + if (errno != EINPROGRESS) { + Error("[%s] connect(%u): %s: forcing down", + pCE->server, cofile, strerror(errno)); + ConsDown(pCE, FLAGTRUE, FLAGTRUE); + close(cofile); + return; + } + } + if ((pCE->cofile = + FileOpenFD(cofile, pCE->secured == FLAGTRUE ? clientSSLSocket : simpleSocket)) == (CONSFILE *)0) { + Error + ("[%s] FileOpenFD(%d,%s) failed: forcing down", + pCE->server, cofile, + pCE->secured ? "clientSSLSocket" : "simpleSocket"); + ConsDown(pCE, FLAGTRUE, FLAGTRUE); + close(cofile); + return; + } + + if (ret == 0) { + pCE->ioState = ISNORMAL; + pCE->stateTimer = 0; + } else { + pCE->ioState = INCONNECT; + pCE->stateTimer = time((time_t *)0) + CONNECTTIMEOUT; + if (timers[T_STATE] == (time_t)0 || + timers[T_STATE] > pCE->stateTimer) + timers[T_STATE] = pCE->stateTimer; + } + pCE->fup = 1; + } + break; } if (!pCE->fup) { @@ -1150,6 +1299,10 @@ ipmi_sol_error: case IPMI: Verbose("[%s] on %s", pCE->server); break; + case REALCOM: + Verbose("[%s] port %hu:%hu on %s", pCE->server, + pCE->netport, pCE->netport+16, pCE->host); + break; case NOOP: Verbose("[%s] noop", pCE->server); break; @@ -1174,6 +1327,18 @@ ipmi_sol_error: maxfd = cofile + 1; } + if (cocmd != -1) { + /* if we're waiting for connect() to finish, watch the + * write bit, otherwise watch for the read bit + */ + if (pCE->ioState == INCONNECT) + FD_SET(cocmd, &winit); + else + FD_SET(cocmd, &rinit); + if (maxfd < cocmd + 1) + maxfd = cocmd + 1; + } + tyme = time((time_t *)0); if (pCE->ioState == ISNORMAL) { diff --git b/conserver/consent.h a/conserver/consent.h index 14c1338..ef36f8a 100644 --- b/conserver/consent.h +++ a/conserver/consent.h @@ -58,7 +58,8 @@ typedef enum consType { HOST, NOOP, UDS, - IPMI + IPMI, + REALCOM } CONSTYPE; typedef enum ipmiIntf { @@ -97,6 +98,7 @@ typedef struct consent { /* console information */ #if defined(CRTSCTS) FLAG crtscts; /* use hardware flow control */ #endif + /* type == REALCOM */ FLAG secured; #if HAVE_OPENSSL SSL_CTX *ssl_ctx; @@ -154,6 +156,7 @@ typedef struct consent { /* console information */ /*** runtime settings ***/ CONSFILE *fdlog; /* the local log file */ CONSFILE *cofile; /* the port to talk to machine on */ + CONSFILE *cocmd; /* the command port to talk to */ char *execSlave; /* pseudo-device slave side */ int execSlaveFD; /* fd of slave side */ pid_t ipid; /* pid of virtual command */ diff --git b/conserver/group.c a/conserver/group.c index 017c78b..0e996df 100644 --- b/conserver/group.c +++ a/conserver/group.c @@ -2234,6 +2234,11 @@ CommandExamine(pGE, pCLServing, pCEServing, tyme, args) b = "IPMI"; p = ' '; break; + case REALCOM: + d = BuildTmpStringPrint("%s/%hu", pCE->host, pCE->netport); + b = "RealC"; + p = ' '; + break; case HOST: d = BuildTmpStringPrint("%s/%hu", pCE->host, pCE->netport); b = "Netwk"; @@ -2429,6 +2434,12 @@ CommandInfo(pGE, pCLServing, pCEServing, tyme, args) pCE->host, FileFDNum(pCE->cofile)); break; + case REALCOM: + FilePrint(pCLServing->fd, FLAGTRUE, "!:%s,%hu,%d,%d:", + pCE->host, pCE->netport, + FileFDNum(pCE->cofile), + FileFDNum(pCE->cocmd)); + break; case HOST: FilePrint(pCLServing->fd, FLAGTRUE, "!:%s,%hu,%s,%d:", pCE->host, pCE->netport, @@ -2668,6 +2679,228 @@ TelOpt(o) void #if PROTOTYPES +DoRealCOMPortInit(CONSENT *pCEServing) +#else +DoRealCOMPortInit(pCEServing) + CONSENT *pCEServing; +#endif +{ + unsigned char cmd[10]; + int nr; + char baud; + int mode; + + int cocmd = FileFDNum(pCEServing->cocmd); + + mode = (pCEServing->cstopb == FLAGTRUE) ? ASPP_IOCTL_STOP2 : ASPP_IOCTL_STOP1; + + if (pCEServing->parity != (PARITY *)0 && pCEServing->parity->iset & PARENB) + { + switch (pCEServing->parity->iset & CSIZE) { + case CS7: + mode |= ASPP_IOCTL_BITS7; + break; + case CS8: + default: + mode |= ASPP_IOCTL_BITS8; + break; + } +#ifdef CMSPAR + if (pCEServing->parity->iset & CMSPAR) + if (pCEServing->parity->iset & PARODD) + mode |= ASPP_IOCTL_MARK; + else + mode |= ASPP_IOCTL_SPACE; + else +#endif + if (pCEServing->parity->iset & PARODD) + mode |= ASPP_IOCTL_ODD; + else + mode |= ASPP_IOCTL_EVEN; + } else { + mode |= ASPP_IOCTL_BITS8; + mode |= ASPP_IOCTL_NONE; + } + + if (pCEServing->baud == (BAUD *)0) { + baud = ASPP_IOCTL_B115200; + } else { + switch (pCEServing->baud->irate) { + case B921600: + baud = ASPP_IOCTL_B921600; + break; + case B460800: + baud = ASPP_IOCTL_B460800; + break; + case B230400: + baud = ASPP_IOCTL_B230400; + break; + case B115200: + baud = ASPP_IOCTL_B115200; + break; + case B57600: + baud = ASPP_IOCTL_B57600; + break; + case B38400: + baud = ASPP_IOCTL_B38400; + break; + case B19200: + baud = ASPP_IOCTL_B19200; + break; + case B9600: + baud = ASPP_IOCTL_B9600; + break; + case B4800: + baud = ASPP_IOCTL_B4800; + break; + case B2400: + baud = ASPP_IOCTL_B2400; + break; + case B1200: + baud = ASPP_IOCTL_B1200; + break; + case B600: + baud = ASPP_IOCTL_B600; + break; + case B300: + baud = ASPP_IOCTL_B300; + break; + case B150: + baud = ASPP_IOCTL_B150; + break; + case B134: + baud = ASPP_IOCTL_B134; + break; + case B110: + baud = ASPP_IOCTL_B110; + break; + case B75: + baud = ASPP_IOCTL_B75; + break; + case B50: + baud = ASPP_IOCTL_B50; + break; + default: + baud = 0xff; + break; + } + } + + cmd[0] = ASPP_CMD_PORT_INIT; + cmd[1] = 8; + cmd[2] = baud; + cmd[3] = mode & 0xff; + cmd[4] = 0; // modem_control & UART_MCR_DTR + cmd[5] = 0; // modem_control & UART_MCR_RTS +#if defined(CRTSCTS) + cmd[6] = pCEServing->crtscts == FLAGTRUE; + cmd[7] = cmd[6]; +#else + cmd[6] = cmd[7] = 0; +#endif + cmd[8] = pCEServing->ixon == FLAGTRUE; + cmd[9] = pCEServing->ixoff == FLAGTRUE; + + if ((nr = + FileWrite(pCEServing->cocmd, FLAGFALSE, cmd, sizeof(cmd))) < 0) { + Error("[%s] write failure: unexpected EOF", pCEServing->server); + ConsoleError(pCEServing); + return; + } + CONDDEBUG((1, "DoRealCOMPortInit(): write %d bytes to fd %d", nr, + cocmd)); +} + +void +#if PROTOTYPES +DoRealCOMCmdParse(CONSENT *pCEServing) +#else +DoRealCOMCmdParse(pCEServing) + CONSENT *pCEServing; +#endif +{ + unsigned char buf[BUFSIZ], cmd[BUFSIZ]; + int nr, i; + int len; + + int cocmd = FileFDNum(pCEServing->cocmd); + + if (!pCEServing->fup) { + FD_CLR(cocmd, &rinit); + FD_CLR(cocmd, &winit); + return; + } + + if ((nr = + FileRead(pCEServing->cocmd, buf, sizeof(buf))) < 0) { + Error("[%s] read failure: unexpected EOF", pCEServing->server); + ConsoleError(pCEServing); + return; + } + CONDDEBUG((1, "DoRealCOMCmdParse(): read %d bytes from fd %d", nr, + cocmd)); + + i = 0; + len = nr; + while (len > 0) { + switch (buf[i]) { + case ASPP_CMD_POLLING: + if (len < 3) { + len = 0; + continue; + } + cmd[0] = ASPP_CMD_ALIVE; + cmd[1] = 1; + cmd[2] = buf[i+2]; + if ((nr = + FileWrite(pCEServing->cocmd, FLAGFALSE, cmd, 3)) < 0) { + Error("[%s] write failure: unexpected EOF", pCEServing->server); + ConsoleError(pCEServing); + len = 0; + continue; + } + CONDDEBUG((1, "DoRealCOMCmdParse(): write %d bytes to fd %d", nr, + cocmd)); + break; + + case ASPP_CMD_NOTIFY : + case ASPP_CMD_WAIT_OQUEUE : + case ASPP_CMD_OQUEUE : + case ASPP_CMD_IQUEUE : + nr = 4; + break; + + case ASPP_CMD_LSTATUS : + case ASPP_CMD_PORT_INIT: + nr = 5; + break; + case ASPP_CMD_FLOWCTRL: + case ASPP_CMD_IOCTL: + case ASPP_CMD_SETBAUD: + case ASPP_CMD_LINECTRL: + case ASPP_CMD_START_BREAK: + case ASPP_CMD_STOP_BREAK: + case ASPP_CMD_START_NOTIFY: + case ASPP_CMD_STOP_NOTIFY: + case ASPP_CMD_FLUSH: + case ASPP_CMD_HOST: + case ASPP_CMD_TX_FIFO: + case ASPP_CMD_XONXOFF: + case ASPP_CMD_SETXON: + case ASPP_CMD_SETXOFF: + nr = 3; + break; + default : + nr = len; + break; + } + i += nr; + len -= nr; + } +} + +void +#if PROTOTYPES DoConsoleRead(CONSENT *pCEServing) #else DoConsoleRead(pCEServing) @@ -4217,6 +4450,16 @@ FlushConsole(pCEServing) break; } +#if 0 + if (pCEServing->cocmd != NULL && + !FileBufEmpty(pCEServing->cocmd)) { + CONDDEBUG((1, + "Kiddie(): heavy IAC (wait for flush) for [%s]", + pCEServing->server)); + break; + } +#endif + /* Do the operation */ if (next >= '0' && next <= '9') { int delay = BREAKDELAYDEFAULT; @@ -4682,8 +4925,10 @@ Kiddie(pGE, sfd) socklen_t slen; int flags = 0; int cofile = FileFDNum(pCEServing->cofile); + int cocmd = FileFDNum(pCEServing->cocmd); slen = sizeof(flags); + if (pCEServing->type == REALCOM) { #if HAVE_OPENSSL if (pCEServing->secured == FLAGTRUE) { int r; @@ -4703,6 +4948,8 @@ Kiddie(pGE, sfd) } } #endif + DoRealCOMPortInit(pCEServing); + } /* So, getsockopt seems to return -1 if there is * something interesting in SO_ERROR under @@ -4745,6 +4992,10 @@ Kiddie(pGE, sfd) */ FD_SET(cofile, &rinit); FD_CLR(cofile, &winit); + if (cocmd != -1) { + FD_SET(cocmd, &rinit); + FD_CLR(cocmd, &winit); + } if (pCEServing->idletimeout != (time_t)0 && (timers[T_CIDLE] == (time_t)0 || timers[T_CIDLE] > @@ -4764,6 +5015,8 @@ Kiddie(pGE, sfd) case ISNORMAL: if (FileCanRead(pCEServing->cofile, &rmask, &wmask)) DoConsoleRead(pCEServing); + if (FileCanRead(pCEServing->cocmd, &rmask, &wmask)) + DoRealCOMCmdParse(pCEServing); if (FileCanRead(pCEServing->initfile, &rmask, &wmask)) DoCommandRead(pCEServing); /* fall through to ISFLUSHING for buffered data */ diff --git b/conserver/main.c a/conserver/main.c index 58a3134..fda2bf6 100644 --- b/conserver/main.c +++ a/conserver/main.c @@ -953,6 +953,15 @@ DumpDataStructures() "DumpDataStructures(): host=%s", EMPTYSTR(pCE->host))); break; + case REALCOM: + CONDDEBUG((1, + "DumpDataStructures(): server=%s, type=REALCOM", + EMPTYSTR(pCE->server))); + CONDDEBUG((1, + "DumpDataStructures(): host=%s, netport=%hu, port=%hu:%hu", + EMPTYSTR(pCE->host), + pCE->netport, pCE->port, pCE->port+16)); + break; case HOST: CONDDEBUG((1, "DumpDataStructures(): server=%s, type=HOST", diff --git b/conserver/readcfg.c a/conserver/readcfg.c index ea6ab1b..fbde4fd 100644 --- b/conserver/readcfg.c +++ a/conserver/readcfg.c @@ -2539,6 +2539,8 @@ ProcessType(c, id) } if (strcasecmp("device", id) == 0) t = DEVICE; + else if (strcasecmp("realcom", id) == 0) + t = REALCOM; else if (strcasecmp("ipmi", id) == 0) t = IPMI; else if (strcasecmp("exec", id) == 0) @@ -2707,6 +2709,20 @@ ConsoleEnd() invalid = 1; } break; + case REALCOM: + if (parserConsoleTemp->host == (char *)0) { + if (isMaster) + Error("[%s] console missing 'host' attribute [%s:%d]", + parserConsoleTemp->server, file, line); + invalid = 1; + } + if (parserConsoleTemp->port == 0) { + if (isMaster) + Error("[%s] console missing 'port' attribute [%s:%d]", + parserConsoleTemp->server, file, line); + invalid = 1; + } + break; case HOST: if (parserConsoleTemp->host == (char *)0) { if (isMaster) @@ -3090,6 +3106,17 @@ ConsoleAdd(c) FD_SET(cofile, &winit); } +#if 0 + if (pCEmatch->cocmd != (CONSFILE *)0) { + int cofile = FileFDNum(pCEmatch->cocmd); + FD_SET(cofile, &rinit); + if (maxfd < cofile + 1) + maxfd = cofile + 1; + if (!FileBufEmpty(pCEmatch->cocmd)) + FD_SET(cofile, &winit); + } +#endif + if (pCEmatch->initfile != (CONSFILE *)0) { int initfile = FileFDNum(pCEmatch->initfile); FD_SET(initfile, &rinit); @@ -3218,6 +3245,56 @@ ConsoleAdd(c) } #endif break; + case REALCOM: + if (pCEmatch->host != (char *)0 && c->host != (char *)0) { + if (strcasecmp(pCEmatch->host, c->host) != 0) { + SwapStr(&pCEmatch->host, &c->host); + closeMatch = 0; + } + } else if (pCEmatch->host != (char *)0 || + c->host != (char *)0) { + SwapStr(&pCEmatch->host, &c->host); + closeMatch = 0; + } + if (pCEmatch->netport != c->netport) { + pCEmatch->netport = c->netport; + closeMatch = 0; + } + if (pCEmatch->secured != c->secured) { + pCEmatch->secured = c->secured; + closeMatch = 0; + } + if (pCEmatch->baud != c->baud) { + pCEmatch->baud = c->baud; + closeMatch = 0; + } + if (pCEmatch->parity != c->parity) { + pCEmatch->parity = c->parity; + closeMatch = 0; + } + if (pCEmatch->cstopb != c->cstopb) { + pCEmatch->cstopb = c->cstopb; + closeMatch = 0; + } + if (pCEmatch->ixany != c->ixany) { + pCEmatch->ixany = c->ixany; + closeMatch = 0; + } + if (pCEmatch->ixon != c->ixon) { + pCEmatch->ixon = c->ixon; + closeMatch = 0; + } + if (pCEmatch->ixoff != c->ixoff) { + pCEmatch->ixoff = c->ixoff; + closeMatch = 0; + } +#if defined(CRTSCTS) + if (pCEmatch->crtscts != c->crtscts) { + pCEmatch->crtscts = c->crtscts; + closeMatch = 0; + } +#endif + break; case IPMI: if (pCEmatch->host != (char *)0 && c->host != (char *)0) { if (strcasecmp(pCEmatch->host, c->host) != 0) { @@ -3424,6 +3501,11 @@ ConsoleDestroy() * user can shoot himself in the foot with a bad config * file, but it won't hurt too much. */ + if (c->type == REALCOM) + c->netport = c->portbase + + ((c->port-1) / c->portinc) * c->portinc * 2 + + ((c->port-1) % c->portinc); + else c->netport = c->portbase + c->portinc * c->port; /* prepare for substitutions */ @@ -3561,6 +3643,7 @@ ConsoleDestroy() (c->exec != (char *)0 ? c->exec : "/bin/sh")), s); break; + case REALCOM: case HOST: BuildString(BuildTmpStringPrint ("!:%s,%hu", c->host, c->netport), s); diff --git b/conserver/group.h a/conserver/group.h index e23d8c3..bc99567 100644 --- b/conserver/group.h +++ a/conserver/group.h @@ -50,6 +50,70 @@ #define AUTH_NOUSER 1 /* no user */ #define AUTH_INVALID 2 /* invalid password */ +/* + * Moxa tty definition + */ +#define ASPP_CMD_NOTIFY 0x26 +#define ASPP_CMD_POLLING 0x27 +#define ASPP_CMD_ALIVE 0x28 + +#define ASPP_CMD_IOCTL 16 +#define ASPP_CMD_FLOWCTRL 17 +#define ASPP_CMD_LSTATUS 19 +#define ASPP_CMD_LINECTRL 18 +#define ASPP_CMD_FLUSH 20 +#define ASPP_CMD_OQUEUE 22 +#define ASPP_CMD_SETBAUD 23 +#define ASPP_CMD_START_BREAK 33 +#define ASPP_CMD_STOP_BREAK 34 +#define ASPP_CMD_START_NOTIFY 36 +#define ASPP_CMD_STOP_NOTIFY 37 +#define ASPP_CMD_HOST 43 +#define ASPP_CMD_PORT_INIT 44 +#define ASPP_CMD_WAIT_OQUEUE 47 + +#define ASPP_CMD_IQUEUE 21 +#define ASPP_CMD_XONXOFF 24 +#define ASPP_CMD_PORT_RESET 32 +#define ASPP_CMD_RESENT_TIME 46 +#define ASPP_CMD_TX_FIFO 48 +#define ASPP_CMD_SETXON 51 +#define ASPP_CMD_SETXOFF 52 + +#define ASPP_IOCTL_B300 0 +#define ASPP_IOCTL_B600 1 +#define ASPP_IOCTL_B1200 2 +#define ASPP_IOCTL_B2400 3 +#define ASPP_IOCTL_B4800 4 +#define ASPP_IOCTL_B7200 5 +#define ASPP_IOCTL_B9600 6 +#define ASPP_IOCTL_B19200 7 +#define ASPP_IOCTL_B38400 8 +#define ASPP_IOCTL_B57600 9 +#define ASPP_IOCTL_B115200 10 +#define ASPP_IOCTL_B230400 11 +#define ASPP_IOCTL_B460800 12 +#define ASPP_IOCTL_B921600 13 +#define ASPP_IOCTL_B150 14 +#define ASPP_IOCTL_B134 15 +#define ASPP_IOCTL_B110 16 +#define ASPP_IOCTL_B75 17 +#define ASPP_IOCTL_B50 18 + +#define ASPP_IOCTL_BITS8 3 +#define ASPP_IOCTL_BITS7 2 +#define ASPP_IOCTL_BITS6 1 +#define ASPP_IOCTL_BITS5 0 + +#define ASPP_IOCTL_STOP1 0 +#define ASPP_IOCTL_STOP2 4 + +#define ASPP_IOCTL_EVEN 8 +#define ASPP_IOCTL_ODD 16 +#define ASPP_IOCTL_MARK 24 +#define ASPP_IOCTL_SPACE 32 +#define ASPP_IOCTL_NONE 0 + typedef struct grpent { /* group info */ unsigned int id; /* uniqueue group id */ unsigned short port; /* port group listens on */