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