|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)ventel.c 5.1 (Berkeley) 4/30/85";
9: #endif not lint
10:
11: /*
12: * Routines for calling up on a Ventel Modem
13: * The Ventel is expected to be strapped for local echo (just like uucp)
14: */
15: #include "tip.h"
16:
17: #define MAXRETRY 5
18:
19: static int sigALRM();
20: static int timeout = 0;
21: static jmp_buf timeoutbuf;
22:
23: /*
24: * some sleep calls have been replaced by this macro
25: * because some ventel modems require two <cr>s in less than
26: * a second in order to 'wake up'... yes, it is dirty...
27: */
28: #define delay(num,denom) busyloop(CPUSPEED*num/denom)
29: #define CPUSPEED 1000000 /* VAX 780 is 1MIPS */
30: #define DELAY(n) { register long N = (n); while (--N > 0); }
31: busyloop(n) { DELAY(n); }
32:
33: ven_dialer(num, acu)
34: register char *num;
35: char *acu;
36: {
37: register char *cp;
38: register int connected = 0;
39: char *msg, *index(), line[80];
40:
41: /*
42: * Get in synch with a couple of carriage returns
43: */
44: if (!vensync(FD)) {
45: 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: printf("\ndialing...");
53: fflush(stdout);
54: ioctl(FD, TIOCHPCL, 0);
55: echo("#k$\r$\n$D$I$A$L$:$ ");
56: for (cp = num; *cp; cp++) {
57: delay(1, 10);
58: write(FD, cp, 1);
59: }
60: delay(1, 10);
61: write(FD, "\r", 1);
62: gobble('\n', line);
63: if (gobble('\n', line))
64: connected = gobble('!', line);
65: ioctl(FD, TIOCFLUSH);
66: #ifdef ACULOG
67: if (timeout) {
68: sprintf(line, "%d second dial timeout",
69: number(value(DIALTIMEOUT)));
70: logent(value(HOST), num, "ventel", line);
71: }
72: #endif
73: if (timeout)
74: ven_disconnect(); /* insurance */
75: if (connected || timeout || !boolean(value(VERBOSE)))
76: return (connected);
77: /* call failed, parse response for user */
78: cp = index(line, '\r');
79: if (cp)
80: *cp = '\0';
81: for (cp = line; cp = index(cp, ' '); cp++)
82: if (cp[1] == ' ')
83: break;
84: if (cp) {
85: while (*cp == ' ')
86: cp++;
87: msg = cp;
88: while (*cp) {
89: if (isupper(*cp))
90: *cp = tolower(*cp);
91: cp++;
92: }
93: printf("%s...", msg);
94: }
95: return (connected);
96: }
97:
98: ven_disconnect()
99: {
100:
101: close(FD);
102: }
103:
104: ven_abort()
105: {
106:
107: write(FD, "\03", 1);
108: close(FD);
109: }
110:
111: static int
112: echo(s)
113: register char *s;
114: {
115: char c;
116:
117: while (c = *s++) switch (c) {
118:
119: case '$':
120: read(FD, &c, 1);
121: s++;
122: break;
123:
124: case '#':
125: c = *s++;
126: write(FD, &c, 1);
127: break;
128:
129: default:
130: write(FD, &c, 1);
131: read(FD, &c, 1);
132: }
133: }
134:
135: static int
136: sigALRM()
137: {
138:
139: printf("\07timeout waiting for reply\n");
140: timeout = 1;
141: longjmp(timeoutbuf, 1);
142: }
143:
144: static int
145: gobble(match, response)
146: register char match;
147: char response[];
148: {
149: register char *cp = response;
150: char c;
151: int (*f)();
152:
153: signal(SIGALRM, sigALRM);
154: timeout = 0;
155: do {
156: if (setjmp(timeoutbuf)) {
157: signal(SIGALRM, f);
158: *cp = '\0';
159: return (0);
160: }
161: alarm(number(value(DIALTIMEOUT)));
162: read(FD, cp, 1);
163: alarm(0);
164: c = (*cp++ &= 0177);
165: #ifdef notdef
166: if (boolean(value(VERBOSE)))
167: putchar(c);
168: #endif
169: } while (c != '\n' && c != match);
170: signal(SIGALRM, SIG_DFL);
171: *cp = '\0';
172: return (c == match);
173: }
174:
175: #define min(a,b) ((a)>(b)?(b):(a))
176: /*
177: * This convoluted piece of code attempts to get
178: * the ventel in sync. If you don't have FIONREAD
179: * there are gory ways to simulate this.
180: */
181: static int
182: vensync(fd)
183: {
184: int already = 0, nread;
185: char buf[60];
186:
187: /*
188: * Toggle DTR to force anyone off that might have left
189: * the modem connected, and insure a consistent state
190: * to start from.
191: *
192: * If you don't have the ioctl calls to diddle directly
193: * with DTR, you can always try setting the baud rate to 0.
194: */
195: ioctl(FD, TIOCCDTR, 0);
196: sleep(1);
197: ioctl(FD, TIOCSDTR, 0);
198: while (already < MAXRETRY) {
199: /*
200: * After reseting the modem, send it two \r's to
201: * autobaud on. Make sure to delay between them
202: * so the modem can frame the incoming characters.
203: */
204: write(fd, "\r", 1);
205: delay(1,10);
206: write(fd, "\r", 1);
207: sleep(2);
208: if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) {
209: perror("tip: ioctl");
210: continue;
211: }
212: while (nread > 0) {
213: read(fd, buf, min(nread, 60));
214: if ((buf[nread - 1] & 0177) == '$')
215: return (1);
216: nread -= min(nread, 60);
217: }
218: sleep(1);
219: already++;
220: }
221: return (0);
222: }
223:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.