1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3*0Sstevel@tonic-gate  * Use is subject to license terms.
4*0Sstevel@tonic-gate  */
5*0Sstevel@tonic-gate /*
6*0Sstevel@tonic-gate  * Copyright (c) 1983 Regents of the University of California.
7*0Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
8*0Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
9*0Sstevel@tonic-gate  */
10*0Sstevel@tonic-gate #ident	"%Z%%M%	%I%	%E% SMI"	/* from UCB 1.5 6/25/83 */
11*0Sstevel@tonic-gate 
12*0Sstevel@tonic-gate /*
13*0Sstevel@tonic-gate  * Routines for calling up on a Ventel Modem
14*0Sstevel@tonic-gate  * Define VENNOECHO if the Ventel is strapped for "no echo".
15*0Sstevel@tonic-gate  */
16*0Sstevel@tonic-gate #include "tip.h"
17*0Sstevel@tonic-gate 
18*0Sstevel@tonic-gate #define	MAXRETRY	5
19*0Sstevel@tonic-gate 
20*0Sstevel@tonic-gate static	void sigALRM();
21*0Sstevel@tonic-gate static	int timeout = 0;
22*0Sstevel@tonic-gate static	sigjmp_buf timeoutbuf;
23*0Sstevel@tonic-gate 
24*0Sstevel@tonic-gate ven_dialer(num, acu)
25*0Sstevel@tonic-gate 	register char *num;
26*0Sstevel@tonic-gate 	char *acu;
27*0Sstevel@tonic-gate {
28*0Sstevel@tonic-gate 	register char *cp;
29*0Sstevel@tonic-gate 	register int connected = 0;
30*0Sstevel@tonic-gate 	struct termios buf;
31*0Sstevel@tonic-gate #ifdef ACULOG
32*0Sstevel@tonic-gate 	char line[80];
33*0Sstevel@tonic-gate #endif
34*0Sstevel@tonic-gate 	/*
35*0Sstevel@tonic-gate 	 * Get in synch with a couple of carriage returns
36*0Sstevel@tonic-gate 	 */
37*0Sstevel@tonic-gate 	if (!vensync(FD)) {
38*0Sstevel@tonic-gate 		printf("can't synchronize with ventel\n");
39*0Sstevel@tonic-gate #ifdef ACULOG
40*0Sstevel@tonic-gate 		logent(value(HOST), num, "ventel", "can't synch up");
41*0Sstevel@tonic-gate #endif
42*0Sstevel@tonic-gate 		return (0);
43*0Sstevel@tonic-gate 	}
44*0Sstevel@tonic-gate 	if (boolean(value(VERBOSE)))
45*0Sstevel@tonic-gate 		printf("\ndialing...");
46*0Sstevel@tonic-gate 	fflush(stdout);
47*0Sstevel@tonic-gate 	ioctl(FD, TCGETS, &buf);
48*0Sstevel@tonic-gate 	buf.c_cflag |= HUPCL;
49*0Sstevel@tonic-gate 	ioctl(FD, TCSETSF, &buf);
50*0Sstevel@tonic-gate #ifdef VENNOECHO
51*0Sstevel@tonic-gate 	echo("#k$\r$\n$D$I$A$L$:$ ");
52*0Sstevel@tonic-gate 	for (cp = num; *cp; cp++) {
53*0Sstevel@tonic-gate 		sleep(1);
54*0Sstevel@tonic-gate 		write(FD, cp, 1);
55*0Sstevel@tonic-gate 	}
56*0Sstevel@tonic-gate 	echo("\r$\n");
57*0Sstevel@tonic-gate #else
58*0Sstevel@tonic-gate 	echo("k$\r$\n$D$I$A$L$:$ <");
59*0Sstevel@tonic-gate 	for (cp = num; *cp; cp++) {
60*0Sstevel@tonic-gate 		char c;
61*0Sstevel@tonic-gate 
62*0Sstevel@tonic-gate 		sleep(1);
63*0Sstevel@tonic-gate 		write(FD, cp, 1);
64*0Sstevel@tonic-gate 		read(FD, &c, 1);
65*0Sstevel@tonic-gate 	}
66*0Sstevel@tonic-gate 	echo(">\r$\n");
67*0Sstevel@tonic-gate #endif
68*0Sstevel@tonic-gate 	if (gobble('\n'))
69*0Sstevel@tonic-gate 		connected = gobble('!');
70*0Sstevel@tonic-gate 	ioctl(FD, TCFLSH, TCIOFLUSH);
71*0Sstevel@tonic-gate #ifdef ACULOG
72*0Sstevel@tonic-gate 	if (timeout) {
73*0Sstevel@tonic-gate 		sprintf(line, "%d second dial timeout",
74*0Sstevel@tonic-gate 			number(value(DIALTIMEOUT)));
75*0Sstevel@tonic-gate 		logent(value(HOST), num, "ventel", line);
76*0Sstevel@tonic-gate 	}
77*0Sstevel@tonic-gate #endif
78*0Sstevel@tonic-gate 	if (timeout)
79*0Sstevel@tonic-gate 		ven_disconnect();	/* insurance */
80*0Sstevel@tonic-gate 	return (connected);
81*0Sstevel@tonic-gate }
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate ven_disconnect()
84*0Sstevel@tonic-gate {
85*0Sstevel@tonic-gate 
86*0Sstevel@tonic-gate 	close(FD);
87*0Sstevel@tonic-gate }
88*0Sstevel@tonic-gate 
89*0Sstevel@tonic-gate ven_abort()
90*0Sstevel@tonic-gate {
91*0Sstevel@tonic-gate 
92*0Sstevel@tonic-gate 	write(FD, "\03", 1);
93*0Sstevel@tonic-gate 	close(FD);
94*0Sstevel@tonic-gate }
95*0Sstevel@tonic-gate 
96*0Sstevel@tonic-gate static int
97*0Sstevel@tonic-gate echo(s)
98*0Sstevel@tonic-gate 	register char *s;
99*0Sstevel@tonic-gate {
100*0Sstevel@tonic-gate 	char c;
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate 	while (c = *s++) {
103*0Sstevel@tonic-gate 		switch (c) {
104*0Sstevel@tonic-gate 		case '$':
105*0Sstevel@tonic-gate 			read(FD, &c, 1);
106*0Sstevel@tonic-gate 			s++;
107*0Sstevel@tonic-gate 			break;
108*0Sstevel@tonic-gate 
109*0Sstevel@tonic-gate 		case '#':
110*0Sstevel@tonic-gate 			c = *s++;
111*0Sstevel@tonic-gate 			write(FD, &c, 1);
112*0Sstevel@tonic-gate 			break;
113*0Sstevel@tonic-gate 
114*0Sstevel@tonic-gate 		default:
115*0Sstevel@tonic-gate 			write(FD, &c, 1);
116*0Sstevel@tonic-gate 			read(FD, &c, 1);
117*0Sstevel@tonic-gate 		}
118*0Sstevel@tonic-gate 	}
119*0Sstevel@tonic-gate }
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate static void
122*0Sstevel@tonic-gate sigALRM()
123*0Sstevel@tonic-gate {
124*0Sstevel@tonic-gate 
125*0Sstevel@tonic-gate 	printf("\07timeout waiting for reply\n");
126*0Sstevel@tonic-gate 	timeout = 1;
127*0Sstevel@tonic-gate 	siglongjmp(timeoutbuf, 1);
128*0Sstevel@tonic-gate }
129*0Sstevel@tonic-gate 
130*0Sstevel@tonic-gate static int
131*0Sstevel@tonic-gate gobble(match)
132*0Sstevel@tonic-gate 	register char match;
133*0Sstevel@tonic-gate {
134*0Sstevel@tonic-gate 	char c;
135*0Sstevel@tonic-gate 	sig_handler_t f;
136*0Sstevel@tonic-gate 
137*0Sstevel@tonic-gate 	f = signal(SIGALRM, (sig_handler_t)sigALRM);
138*0Sstevel@tonic-gate 	timeout = 0;
139*0Sstevel@tonic-gate 	do {
140*0Sstevel@tonic-gate 		if (sigsetjmp(timeoutbuf, 1)) {
141*0Sstevel@tonic-gate 			signal(SIGALRM, f);
142*0Sstevel@tonic-gate 			return (0);
143*0Sstevel@tonic-gate 		}
144*0Sstevel@tonic-gate 		alarm(number(value(DIALTIMEOUT)));
145*0Sstevel@tonic-gate 		read(FD, &c, 1);
146*0Sstevel@tonic-gate 		alarm(0);
147*0Sstevel@tonic-gate 		c &= 0177;
148*0Sstevel@tonic-gate #ifdef notdef
149*0Sstevel@tonic-gate 		if (boolean(value(VERBOSE)))
150*0Sstevel@tonic-gate 			putchar(c);
151*0Sstevel@tonic-gate #endif
152*0Sstevel@tonic-gate 	} while (c != '\n' && c != match);
153*0Sstevel@tonic-gate 	signal(SIGALRM, SIG_DFL);
154*0Sstevel@tonic-gate 	return (c == match);
155*0Sstevel@tonic-gate }
156*0Sstevel@tonic-gate 
157*0Sstevel@tonic-gate #define	min(a, b)	(((a) > (b)) ? (b) : (a))
158*0Sstevel@tonic-gate /*
159*0Sstevel@tonic-gate  * This convoluted piece of code attempts to get
160*0Sstevel@tonic-gate  * the ventel in sync.  If you don't have FIONREAD
161*0Sstevel@tonic-gate  * there are gory ways to simulate this.
162*0Sstevel@tonic-gate  */
163*0Sstevel@tonic-gate static int
164*0Sstevel@tonic-gate vensync(fd)
165*0Sstevel@tonic-gate {
166*0Sstevel@tonic-gate 	int already = 0, nread;
167*0Sstevel@tonic-gate 	char buf[60];
168*0Sstevel@tonic-gate 	int dtr = TIOCM_DTR;
169*0Sstevel@tonic-gate 
170*0Sstevel@tonic-gate 	/*
171*0Sstevel@tonic-gate 	 * Toggle DTR to force anyone off that might have left
172*0Sstevel@tonic-gate 	 * the modem connected, and insure a consistent state
173*0Sstevel@tonic-gate 	 * to start from.
174*0Sstevel@tonic-gate 	 *
175*0Sstevel@tonic-gate 	 * If you don't have the ioctl calls to diddle directly
176*0Sstevel@tonic-gate 	 * with DTR, you can always try setting the baud rate to 0.
177*0Sstevel@tonic-gate 	 */
178*0Sstevel@tonic-gate 	ioctl(FD, TIOCMBIC, &dtr);
179*0Sstevel@tonic-gate 	sleep(2);
180*0Sstevel@tonic-gate 	ioctl(FD, TIOCMBIS, &dtr);
181*0Sstevel@tonic-gate 	while (already < MAXRETRY) {
182*0Sstevel@tonic-gate 		/*
183*0Sstevel@tonic-gate 		 * After reseting the modem, send it two \r's to
184*0Sstevel@tonic-gate 		 * autobaud on. Make sure to delay between them
185*0Sstevel@tonic-gate 		 * so the modem can frame the incoming characters.
186*0Sstevel@tonic-gate 		 */
187*0Sstevel@tonic-gate 		write(fd, "\r", 1);
188*0Sstevel@tonic-gate #ifdef VMUNIX
189*0Sstevel@tonic-gate 		{
190*0Sstevel@tonic-gate #include <sys/time.h>
191*0Sstevel@tonic-gate 		struct timeval tv = {0, 500000};
192*0Sstevel@tonic-gate 
193*0Sstevel@tonic-gate 		select(0, 0, 0, 0, &tv);
194*0Sstevel@tonic-gate 		}
195*0Sstevel@tonic-gate #else
196*0Sstevel@tonic-gate 		sleep(1);
197*0Sstevel@tonic-gate #endif
198*0Sstevel@tonic-gate 		write(fd, "\r", 1);
199*0Sstevel@tonic-gate 		sleep(3);
200*0Sstevel@tonic-gate 		if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) {
201*0Sstevel@tonic-gate 			perror("tip: ioctl");
202*0Sstevel@tonic-gate 			continue;
203*0Sstevel@tonic-gate 		}
204*0Sstevel@tonic-gate 		while (nread > 0) {
205*0Sstevel@tonic-gate 			read(fd, buf, min(nread, 60));
206*0Sstevel@tonic-gate 			if ((buf[nread - 1] & 0177) == '$')
207*0Sstevel@tonic-gate 				return (1);
208*0Sstevel@tonic-gate 			nread -= min(nread, 60);
209*0Sstevel@tonic-gate 		}
210*0Sstevel@tonic-gate 		sleep(1);
211*0Sstevel@tonic-gate 		already++;
212*0Sstevel@tonic-gate 	}
213*0Sstevel@tonic-gate 	return (0);
214*0Sstevel@tonic-gate }
215