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