10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
30Sstevel@tonic-gate * Use is subject to license terms.
40Sstevel@tonic-gate */
5*549Smuffin
60Sstevel@tonic-gate /*
70Sstevel@tonic-gate * Copyright (c) 1983 Regents of the University of California.
80Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement
90Sstevel@tonic-gate * specifies the terms and conditions for redistribution.
100Sstevel@tonic-gate */
11*549Smuffin
12*549Smuffin #pragma ident "%Z%%M% %I% %E% SMI"
130Sstevel@tonic-gate
140Sstevel@tonic-gate /*
150Sstevel@tonic-gate * Routines for calling up on a Ventel Modem
160Sstevel@tonic-gate * Define VENNOECHO if the Ventel is strapped for "no echo".
170Sstevel@tonic-gate */
180Sstevel@tonic-gate #include "tip.h"
190Sstevel@tonic-gate
200Sstevel@tonic-gate #define MAXRETRY 5
210Sstevel@tonic-gate
22*549Smuffin static int vensync(int);
23*549Smuffin static int gobble(char);
24*549Smuffin static void echo(char *);
25*549Smuffin static void sigALRM(void);
26*549Smuffin static int timeout = 0;
27*549Smuffin static sigjmp_buf timeoutbuf;
280Sstevel@tonic-gate
29*549Smuffin void ven_disconnect(void);
30*549Smuffin
31*549Smuffin /* ARGSUSED */
32*549Smuffin int
ven_dialer(char * num,char * acu)33*549Smuffin ven_dialer(char *num, char *acu)
340Sstevel@tonic-gate {
35*549Smuffin char *cp;
36*549Smuffin int connected = 0;
370Sstevel@tonic-gate struct termios buf;
380Sstevel@tonic-gate #ifdef ACULOG
390Sstevel@tonic-gate char line[80];
400Sstevel@tonic-gate #endif
410Sstevel@tonic-gate /*
420Sstevel@tonic-gate * Get in synch with a couple of carriage returns
430Sstevel@tonic-gate */
440Sstevel@tonic-gate if (!vensync(FD)) {
45*549Smuffin (void) printf("can't synchronize with ventel\n");
460Sstevel@tonic-gate #ifdef ACULOG
470Sstevel@tonic-gate logent(value(HOST), num, "ventel", "can't synch up");
480Sstevel@tonic-gate #endif
490Sstevel@tonic-gate return (0);
500Sstevel@tonic-gate }
510Sstevel@tonic-gate if (boolean(value(VERBOSE)))
52*549Smuffin (void) printf("\ndialing...");
53*549Smuffin (void) fflush(stdout);
54*549Smuffin (void) ioctl(FD, TCGETS, &buf);
550Sstevel@tonic-gate buf.c_cflag |= HUPCL;
56*549Smuffin (void) ioctl(FD, TCSETSF, &buf);
570Sstevel@tonic-gate #ifdef VENNOECHO
580Sstevel@tonic-gate echo("#k$\r$\n$D$I$A$L$:$ ");
590Sstevel@tonic-gate for (cp = num; *cp; cp++) {
60*549Smuffin (void) sleep(1);
61*549Smuffin (void) write(FD, cp, 1);
620Sstevel@tonic-gate }
630Sstevel@tonic-gate echo("\r$\n");
640Sstevel@tonic-gate #else
650Sstevel@tonic-gate echo("k$\r$\n$D$I$A$L$:$ <");
660Sstevel@tonic-gate for (cp = num; *cp; cp++) {
670Sstevel@tonic-gate char c;
680Sstevel@tonic-gate
69*549Smuffin (void) sleep(1);
70*549Smuffin (void) write(FD, cp, 1);
71*549Smuffin (void) read(FD, &c, 1);
720Sstevel@tonic-gate }
730Sstevel@tonic-gate echo(">\r$\n");
740Sstevel@tonic-gate #endif
750Sstevel@tonic-gate if (gobble('\n'))
760Sstevel@tonic-gate connected = gobble('!');
77*549Smuffin (void) ioctl(FD, TCFLSH, TCIOFLUSH);
780Sstevel@tonic-gate #ifdef ACULOG
790Sstevel@tonic-gate if (timeout) {
80*549Smuffin (void) sprintf(line, "%d second dial timeout",
81*549Smuffin number(value(DIALTIMEOUT)));
820Sstevel@tonic-gate logent(value(HOST), num, "ventel", line);
830Sstevel@tonic-gate }
840Sstevel@tonic-gate #endif
850Sstevel@tonic-gate if (timeout)
860Sstevel@tonic-gate ven_disconnect(); /* insurance */
870Sstevel@tonic-gate return (connected);
880Sstevel@tonic-gate }
890Sstevel@tonic-gate
90*549Smuffin void
ven_disconnect(void)91*549Smuffin ven_disconnect(void)
920Sstevel@tonic-gate {
930Sstevel@tonic-gate
94*549Smuffin (void) close(FD);
950Sstevel@tonic-gate }
960Sstevel@tonic-gate
97*549Smuffin void
ven_abort(void)98*549Smuffin ven_abort(void)
990Sstevel@tonic-gate {
1000Sstevel@tonic-gate
101*549Smuffin (void) write(FD, "\03", 1);
102*549Smuffin (void) close(FD);
1030Sstevel@tonic-gate }
1040Sstevel@tonic-gate
105*549Smuffin static void
echo(char * s)106*549Smuffin echo(char *s)
1070Sstevel@tonic-gate {
1080Sstevel@tonic-gate char c;
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate while (c = *s++) {
1110Sstevel@tonic-gate switch (c) {
1120Sstevel@tonic-gate case '$':
113*549Smuffin (void) read(FD, &c, 1);
1140Sstevel@tonic-gate s++;
1150Sstevel@tonic-gate break;
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate case '#':
1180Sstevel@tonic-gate c = *s++;
119*549Smuffin (void) write(FD, &c, 1);
1200Sstevel@tonic-gate break;
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate default:
123*549Smuffin (void) write(FD, &c, 1);
124*549Smuffin (void) read(FD, &c, 1);
1250Sstevel@tonic-gate }
1260Sstevel@tonic-gate }
1270Sstevel@tonic-gate }
1280Sstevel@tonic-gate
1290Sstevel@tonic-gate static void
sigALRM(void)130*549Smuffin sigALRM(void)
1310Sstevel@tonic-gate {
1320Sstevel@tonic-gate
133*549Smuffin (void) printf("\07timeout waiting for reply\n");
1340Sstevel@tonic-gate timeout = 1;
1350Sstevel@tonic-gate siglongjmp(timeoutbuf, 1);
1360Sstevel@tonic-gate }
1370Sstevel@tonic-gate
1380Sstevel@tonic-gate static int
gobble(char match)139*549Smuffin gobble(char match)
1400Sstevel@tonic-gate {
1410Sstevel@tonic-gate char c;
1420Sstevel@tonic-gate sig_handler_t f;
1430Sstevel@tonic-gate
1440Sstevel@tonic-gate f = signal(SIGALRM, (sig_handler_t)sigALRM);
1450Sstevel@tonic-gate timeout = 0;
1460Sstevel@tonic-gate do {
1470Sstevel@tonic-gate if (sigsetjmp(timeoutbuf, 1)) {
148*549Smuffin (void) signal(SIGALRM, f);
1490Sstevel@tonic-gate return (0);
1500Sstevel@tonic-gate }
151*549Smuffin (void) alarm(number(value(DIALTIMEOUT)));
152*549Smuffin (void) read(FD, &c, 1);
153*549Smuffin (void) alarm(0);
1540Sstevel@tonic-gate c &= 0177;
1550Sstevel@tonic-gate #ifdef notdef
1560Sstevel@tonic-gate if (boolean(value(VERBOSE)))
157*549Smuffin (void) putchar(c);
1580Sstevel@tonic-gate #endif
1590Sstevel@tonic-gate } while (c != '\n' && c != match);
160*549Smuffin (void) signal(SIGALRM, SIG_DFL);
1610Sstevel@tonic-gate return (c == match);
1620Sstevel@tonic-gate }
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate #define min(a, b) (((a) > (b)) ? (b) : (a))
1650Sstevel@tonic-gate /*
1660Sstevel@tonic-gate * This convoluted piece of code attempts to get
1670Sstevel@tonic-gate * the ventel in sync. If you don't have FIONREAD
1680Sstevel@tonic-gate * there are gory ways to simulate this.
1690Sstevel@tonic-gate */
1700Sstevel@tonic-gate static int
vensync(int fd)171*549Smuffin vensync(int fd)
1720Sstevel@tonic-gate {
1730Sstevel@tonic-gate int already = 0, nread;
1740Sstevel@tonic-gate char buf[60];
1750Sstevel@tonic-gate int dtr = TIOCM_DTR;
1760Sstevel@tonic-gate
1770Sstevel@tonic-gate /*
1780Sstevel@tonic-gate * Toggle DTR to force anyone off that might have left
1790Sstevel@tonic-gate * the modem connected, and insure a consistent state
1800Sstevel@tonic-gate * to start from.
1810Sstevel@tonic-gate *
1820Sstevel@tonic-gate * If you don't have the ioctl calls to diddle directly
1830Sstevel@tonic-gate * with DTR, you can always try setting the baud rate to 0.
1840Sstevel@tonic-gate */
185*549Smuffin (void) ioctl(FD, TIOCMBIC, &dtr);
186*549Smuffin (void) sleep(2);
187*549Smuffin (void) ioctl(FD, TIOCMBIS, &dtr);
1880Sstevel@tonic-gate while (already < MAXRETRY) {
1890Sstevel@tonic-gate /*
1900Sstevel@tonic-gate * After reseting the modem, send it two \r's to
1910Sstevel@tonic-gate * autobaud on. Make sure to delay between them
1920Sstevel@tonic-gate * so the modem can frame the incoming characters.
1930Sstevel@tonic-gate */
194*549Smuffin (void) write(fd, "\r", 1);
1950Sstevel@tonic-gate #ifdef VMUNIX
1960Sstevel@tonic-gate {
1970Sstevel@tonic-gate #include <sys/time.h>
1980Sstevel@tonic-gate struct timeval tv = {0, 500000};
1990Sstevel@tonic-gate
200*549Smuffin (void) select(0, 0, 0, 0, &tv);
2010Sstevel@tonic-gate }
2020Sstevel@tonic-gate #else
203*549Smuffin (void) sleep(1);
2040Sstevel@tonic-gate #endif
205*549Smuffin (void) write(fd, "\r", 1);
206*549Smuffin (void) sleep(3);
2070Sstevel@tonic-gate if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) {
2080Sstevel@tonic-gate perror("tip: ioctl");
2090Sstevel@tonic-gate continue;
2100Sstevel@tonic-gate }
2110Sstevel@tonic-gate while (nread > 0) {
212*549Smuffin (void) read(fd, buf, min(nread, 60));
2130Sstevel@tonic-gate if ((buf[nread - 1] & 0177) == '$')
2140Sstevel@tonic-gate return (1);
2150Sstevel@tonic-gate nread -= min(nread, 60);
2160Sstevel@tonic-gate }
217*549Smuffin (void) sleep(1);
2180Sstevel@tonic-gate already++;
2190Sstevel@tonic-gate }
2200Sstevel@tonic-gate return (0);
2210Sstevel@tonic-gate }
222