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