xref: /original-bsd/usr.bin/tip/aculib/ventel.c (revision 8c533fbc)
1 #ifndef lint
2 static char sccsid[] = "@(#)ventel.c	1.5 (Berkeley) 06/25/83";
3 #endif
4 
5 /*
6  * Routines for calling up on a Ventel Modem
7  * The Ventel is expected to be strapped for "no echo".
8  */
9 #include "tip.h"
10 
11 #define	MAXRETRY	5
12 
13 static	int sigALRM();
14 static	int timeout = 0;
15 static	jmp_buf timeoutbuf;
16 
17 ven_dialer(num, acu)
18 	register char *num;
19 	char *acu;
20 {
21 	register char *cp;
22 	register int connected = 0;
23 #ifdef ACULOG
24 	char line[80];
25 #endif
26 	/*
27 	 * Get in synch with a couple of carriage returns
28 	 */
29 	if (!vensync(FD)) {
30 		printf("can't synchronize with ventel\n");
31 #ifdef ACULOG
32 		logent(value(HOST), num, "ventel", "can't synch up");
33 #endif
34 		return (0);
35 	}
36 	if (boolean(value(VERBOSE)))
37 		printf("\ndialing...");
38 	fflush(stdout);
39 	ioctl(FD, TIOCHPCL, 0);
40 	echo("#k$\r$\n$D$I$A$L$:$ ");
41 	for (cp = num; *cp; cp++) {
42 		sleep(1);
43 		write(FD, cp, 1);
44 	}
45 	echo("\r$\n");
46 	if (gobble('\n'))
47 		connected = gobble('!');
48 	ioctl(FD, TIOCFLUSH);
49 #ifdef ACULOG
50 	if (timeout) {
51 		sprintf(line, "%d second dial timeout",
52 			number(value(DIALTIMEOUT)));
53 		logent(value(HOST), num, "ventel", line);
54 	}
55 #endif
56 	if (timeout)
57 		ven_disconnect();	/* insurance */
58 	return (connected);
59 }
60 
61 ven_disconnect()
62 {
63 
64 	close(FD);
65 }
66 
67 ven_abort()
68 {
69 
70 	write(FD, "\03", 1);
71 	close(FD);
72 }
73 
74 static int
75 echo(s)
76 	register char *s;
77 {
78 	char c;
79 
80 	while (c = *s++) switch (c) {
81 
82 	case '$':
83 		read(FD, &c, 1);
84 		s++;
85 		break;
86 
87 	case '#':
88 		c = *s++;
89 		write(FD, &c, 1);
90 		break;
91 
92 	default:
93 		write(FD, &c, 1);
94 		read(FD, &c, 1);
95 	}
96 }
97 
98 static int
99 sigALRM()
100 {
101 
102 	printf("\07timeout waiting for reply\n");
103 	timeout = 1;
104 	longjmp(timeoutbuf, 1);
105 }
106 
107 static int
108 gobble(match)
109 	register char match;
110 {
111 	char c;
112 	int (*f)();
113 
114 	signal(SIGALRM, sigALRM);
115 	timeout = 0;
116 	do {
117 		if (setjmp(timeoutbuf)) {
118 			signal(SIGALRM, f);
119 			return (0);
120 		}
121 		alarm(number(value(DIALTIMEOUT)));
122 		read(FD, &c, 1);
123 		alarm(0);
124 		c &= 0177;
125 #ifdef notdef
126 		if (boolean(value(VERBOSE)))
127 			putchar(c);
128 #endif
129 	} while (c != '\n' && c != match);
130 	signal(SIGALRM, SIG_DFL);
131 	return (c == match);
132 }
133 
134 #define min(a,b)	((a)>(b)?(b):(a))
135 /*
136  * This convoluted piece of code attempts to get
137  * the ventel in sync.  If you don't have FIONREAD
138  * there are gory ways to simulate this.
139  */
140 static int
141 vensync(fd)
142 {
143 	int already = 0, nread;
144 	char buf[60];
145 
146 	/*
147 	 * Toggle DTR to force anyone off that might have left
148 	 * the modem connected, and insure a consistent state
149 	 * to start from.
150 	 *
151 	 * If you don't have the ioctl calls to diddle directly
152 	 * with DTR, you can always try setting the baud rate to 0.
153 	 */
154 	ioctl(FD, TIOCCDTR, 0);
155 	sleep(2);
156 	ioctl(FD, TIOCSDTR, 0);
157 	while (already < MAXRETRY) {
158 		/*
159 		 * After reseting the modem, send it two \r's to
160 		 * autobaud on. Make sure to delay between them
161 		 * so the modem can frame the incoming characters.
162 		 */
163 		write(fd, "\r", 1);
164 		sleep(1);
165 		write(fd, "\r", 1);
166 		sleep(3);
167 		if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) {
168 			perror("tip: ioctl");
169 			continue;
170 		}
171 		while (nread > 0) {
172 			read(fd, buf, min(nread, 60));
173 			if ((buf[nread - 1] & 0177) == '$')
174 				return (1);
175 			nread -= min(nread, 60);
176 		}
177 		sleep(1);
178 		already++;
179 	}
180 	return (0);
181 }
182