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