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