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