|
|
1.1 root 1: /*
2: * Copyright (c) 1983 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: static char sccsid[] = "@(#)hayes.c 5.3 (Berkeley) 6/1/90";
22: #endif /* not lint */
23:
24: /*
25: * Routines for calling up on a Hayes Modem
26: * (based on the old VenTel driver).
27: * The modem is expected to be strapped for "echo".
28: * Also, the switches enabling the DTR and CD lines
29: * must be set correctly.
30: * NOTICE:
31: * The easy way to hang up a modem is always simply to
32: * clear the DTR signal. However, if the +++ sequence
33: * (which switches the modem back to local mode) is sent
34: * before modem is hung up, removal of the DTR signal
35: * has no effect (except that it prevents the modem from
36: * recognizing commands).
37: * (by Helge Skrivervik, Calma Company, Sunnyvale, CA. 1984)
38: */
39: /*
40: * TODO:
41: * It is probably not a good idea to switch the modem
42: * state between 'verbose' and terse (status messages).
43: * This should be kicked out and we should use verbose
44: * mode only. This would make it consistent with normal
45: * interactive use thru the command 'tip dialer'.
46: */
47: #include "tip.h"
48:
49: #define min(a,b) ((a < b) ? a : b)
50:
51: static int sigALRM();
52: static int timeout = 0;
53: static jmp_buf timeoutbuf;
54: static char gobble();
55: #define DUMBUFLEN 40
56: static char dumbuf[DUMBUFLEN];
57:
58: #define DIALING 1
59: #define IDLE 2
60: #define CONNECTED 3
61: #define FAILED 4
62: static int state = IDLE;
63:
64: hay_dialer(num, acu)
65: register char *num;
66: char *acu;
67: {
68: register char *cp;
69: register int connected = 0;
70: char dummy;
71: #ifdef ACULOG
72: char line[80];
73: #endif
74: if (hay_sync() == 0) /* make sure we can talk to the modem */
75: return(0);
76: if (boolean(value(VERBOSE)))
77: printf("\ndialing...");
78: fflush(stdout);
79: ioctl(FD, TIOCHPCL, 0);
80: ioctl(FD, TIOCFLUSH, 0); /* get rid of garbage */
81: write(FD, "ATv0\r", 5); /* tell modem to use short status codes */
82: gobble("\r");
83: gobble("\r");
84: write(FD, "ATTD", 4); /* send dial command */
85: write(FD, num, strlen(num));
86: state = DIALING;
87: write(FD, "\r", 1);
88: connected = 0;
89: if (gobble("\r")) {
90: if ((dummy = gobble("01234")) != '1')
91: error_rep(dummy);
92: else
93: connected = 1;
94: }
95: if (connected)
96: state = CONNECTED;
97: else {
98: state = FAILED;
99: return (connected); /* lets get out of here.. */
100: }
101: ioctl(FD, TIOCFLUSH, 0);
102: #ifdef ACULOG
103: if (timeout) {
104: sprintf(line, "%d second dial timeout",
105: number(value(DIALTIMEOUT)));
106: logent(value(HOST), num, "hayes", line);
107: }
108: #endif
109: if (timeout)
110: hay_disconnect(); /* insurance */
111: return (connected);
112: }
113:
114:
115: hay_disconnect()
116: {
117: char c;
118: int len, rlen;
119:
120: /* first hang up the modem*/
121: #ifdef DEBUG
122: printf("\rdisconnecting modem....\n\r");
123: #endif
124: ioctl(FD, TIOCCDTR, 0);
125: sleep(1);
126: ioctl(FD, TIOCSDTR, 0);
127: goodbye();
128: }
129:
130: hay_abort()
131: {
132:
133: char c;
134:
135: write(FD, "\r", 1); /* send anything to abort the call */
136: hay_disconnect();
137: }
138:
139: static int
140: sigALRM()
141: {
142:
143: printf("\07timeout waiting for reply\n\r");
144: timeout = 1;
145: longjmp(timeoutbuf, 1);
146: }
147:
148: static char
149: gobble(match)
150: register char *match;
151: {
152: char c;
153: int (*f)();
154: int i, status = 0;
155:
156: signal(SIGALRM, sigALRM);
157: timeout = 0;
158: #ifdef DEBUG
159: printf("\ngobble: waiting for %s\n", match);
160: #endif
161: do {
162: if (setjmp(timeoutbuf)) {
163: signal(SIGALRM, f);
164: return (0);
165: }
166: alarm(number(value(DIALTIMEOUT)));
167: read(FD, &c, 1);
168: alarm(0);
169: c &= 0177;
170: #ifdef DEBUG
171: printf("%c 0x%x ", c, c);
172: #endif
173: for (i = 0; i < strlen(match); i++)
174: if (c == match[i])
175: status = c;
176: } while (status == 0);
177: signal(SIGALRM, SIG_DFL);
178: #ifdef DEBUG
179: printf("\n");
180: #endif
181: return (status);
182: }
183:
184: error_rep(c)
185: register char c;
186: {
187: printf("\n\r");
188: switch (c) {
189:
190: case '0':
191: printf("OK");
192: break;
193:
194: case '1':
195: printf("CONNECT");
196: break;
197:
198: case '2':
199: printf("RING");
200: break;
201:
202: case '3':
203: printf("NO CARRIER");
204: break;
205:
206: case '4':
207: printf("ERROR in input");
208: break;
209:
210: case '5':
211: printf("CONNECT 1200");
212: break;
213:
214: default:
215: printf("Unknown Modem error: %c (0x%x)", c, c);
216: }
217: printf("\n\r");
218: return;
219: }
220:
221: /*
222: * set modem back to normal verbose status codes.
223: */
224: goodbye()
225: {
226: int len, rlen;
227: char c;
228:
229: ioctl(FD, TIOCFLUSH, &len); /* get rid of trash */
230: if (hay_sync()) {
231: sleep(1);
232: #ifndef DEBUG
233: ioctl(FD, TIOCFLUSH, 0);
234: #endif
235: write(FD, "ATH0\r", 5); /* insurance */
236: #ifndef DEBUG
237: c = gobble("03");
238: if (c != '0' && c != '3') {
239: printf("cannot hang up modem\n\r");
240: printf("please use 'tip dialer' to make sure the line is hung up\n\r");
241: }
242: #endif
243: sleep(1);
244: ioctl(FD, FIONREAD, &len);
245: #ifdef DEBUG
246: printf("goodbye1: len=%d -- ", len);
247: rlen = read(FD, dumbuf, min(len, DUMBUFLEN));
248: dumbuf[rlen] = '\0';
249: printf("read (%d): %s\r\n", rlen, dumbuf);
250: #endif
251: write(FD, "ATv1\r", 5);
252: sleep(1);
253: #ifdef DEBUG
254: ioctl(FD, FIONREAD, &len);
255: printf("goodbye2: len=%d -- ", len);
256: rlen = read(FD, dumbuf, min(len, DUMBUFLEN));
257: dumbuf[rlen] = '\0';
258: printf("read (%d): %s\r\n", rlen, dumbuf);
259: #endif
260: }
261: ioctl(FD, TIOCFLUSH, 0); /* clear the input buffer */
262: ioctl(FD, TIOCCDTR, 0); /* clear DTR (insurance) */
263: close(FD);
264: }
265:
266: #define MAXRETRY 5
267:
268: hay_sync()
269: {
270: int len, retry = 0;
271:
272: while (retry++ <= MAXRETRY) {
273: write(FD, "AT\r", 3);
274: sleep(1);
275: ioctl(FD, FIONREAD, &len);
276: if (len) {
277: len = read(FD, dumbuf, min(len, DUMBUFLEN));
278: if (index(dumbuf, '0') ||
279: (index(dumbuf, 'O') && index(dumbuf, 'K')))
280: return(1);
281: #ifdef DEBUG
282: dumbuf[len] = '\0';
283: printf("hay_sync: (\"%s\") %d\n\r", dumbuf, retry);
284: #endif
285: }
286: ioctl(FD, TIOCCDTR, 0);
287: ioctl(FD, TIOCSDTR, 0);
288: }
289: printf("Cannot synchronize with hayes...\n\r");
290: return(0);
291: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.