Add copyright
[unix-history] / usr / src / usr.bin / tip / aculib / hayes.c
CommitLineData
051b1e55
DF
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
e316be98 7#ifndef lint
051b1e55
DF
8static char sccsid[] = "@(#)hayes.c 5.1 (Berkeley) %G%";
9#endif not lint
e316be98
MAN
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
38static int sigALRM();
39static int timeout = 0;
40static jmp_buf timeoutbuf;
41static char gobble();
42#define DUMBUFLEN 40
43static char dumbuf[DUMBUFLEN];
44
45#define DIALING 1
46#define IDLE 2
47#define CONNECTED 3
48#define FAILED 4
49static int state = IDLE;
50
51hay_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
102hay_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
117hay_abort()
118{
119
120 char c;
121
122 write(FD, "\r", 1); /* send anything to abort the call */
123 hay_disconnect();
124}
125
126static int
127sigALRM()
128{
129
130 printf("\07timeout waiting for reply\n\r");
131 timeout = 1;
132 longjmp(timeoutbuf, 1);
133}
134
135static char
136gobble(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
171error_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 */
211goodbye()
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
255hay_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}