1 /*-
2 * Copyright (c) 1985, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.proprietary.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)hys24.c 8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11
12 #include "condevs.h"
13
14 /*
15 * hyspopn24(telno, flds, dev) connect to hayes smartmodem (pulse call)
16 * hystopn24(telno, flds, dev) connect to hayes smartmodem (tone call)
17 *
18 * return codes: >0 - file number - ok CF_DIAL,CF_DEVICE - failed
19 */
20
21 #include <sys/file.h>
22 #include <sys/ioctl.h>
23
hyspopn24(telno,flds,dev)24 hyspopn24(telno, flds, dev)
25 char *telno, *flds[];
26 struct Devices *dev;
27 {
28 return hysopn24(telno, flds, dev, 0);
29 }
30
hystopn24(telno,flds,dev)31 hystopn24(telno, flds, dev)
32 char *telno, *flds[];
33 struct Devices *dev;
34 {
35 return hysopn24(telno, flds, dev, 1);
36 }
37
38 /* ARGSUSED */
hysopn24(telno,flds,dev,toneflag)39 hysopn24(telno, flds, dev, toneflag)
40 char *telno;
41 char *flds[];
42 struct Devices *dev;
43 int toneflag;
44 {
45 int dh = -1;
46 int result, ix, speed;
47 char *ii;
48 extern errno;
49 char dcname[20];
50 char resultbuf[16];
51
52 sprintf(dcname, "/dev/%s", dev->D_line);
53 DEBUG(4, "dc - %s\n", dcname);
54 if (setjmp(Sjbuf)) {
55 logent(dcname, "TIMEOUT");
56 if (dh >= 0)
57 hyscls24(dh, 0);
58 return CF_DIAL;
59 }
60 signal(SIGALRM, alarmtr);
61 getnextfd();
62 alarm(10);
63 dh = open(dcname, 2); /* read/write */
64 alarm(0);
65
66 for (ii = telno; *ii; ii++)
67 if (*ii == '=')
68 *ii = ',';
69
70 /* modem is open */
71 next_fd = -1;
72 if (dh >= 0) {
73 ioctl(dh, TIOCHPCL, 0);
74 fixline(dh, dev->D_speed);
75 if (dochat(dev, flds, dh)) {
76 logent(dcname, "CHAT FAILED");
77 hyscls24(dh, 0);
78 return CF_DIAL;
79 }
80 hyscls24(dh, 1);/* make sure the line is reset */
81 write(dh, "AT&F&D3&C1E0M0X3QV0Y\r", 21);
82 if (expect("0\r", dh) != 0) {
83 logent(dcname, "HSM not responding OK");
84 hyscls24(dh, 0);
85 return CF_DIAL;
86 }
87 if (toneflag)
88 write(dh, "\rATDT", 5);
89 else
90 write(dh, "\rATDP", 5);
91 write(dh, telno, strlen(telno));
92 write(dh, "\r", 1);
93
94 if (setjmp(Sjbuf)) {
95 logent(dcname, "Modem Hung");
96 if (dh >= 0)
97 hyscls24(dh, 0);
98 return CF_DIAL;
99 }
100 signal(SIGALRM, alarmtr);
101 alarm(120);
102 do {
103 for (ix = 0; ix < 16; ix++) {
104 read(dh, resultbuf + ix, 1);
105 DEBUG(6, "character read = 0x%X \n", resultbuf[ix]);
106 if ((0x7f & resultbuf[ix]) == 0xd)
107 break;
108 }
109
110 result = atol(resultbuf);
111 switch (result) {
112 case 0:
113 logent("HSM Spurious OK response", _FAILED);
114 speed = 0;
115 break;
116 case 1:
117 logent("HSM connected at 300 baud!", _FAILED);
118 speed = -1;
119 break;
120 case 2:
121 speed = 0;
122 DEBUG(4, "Ringing", 0);
123 break;
124 case 3:
125 logent("HSM No Carrier", _FAILED);
126 speed = -1;
127 break;
128 case 4:
129 logent("HSM Error", _FAILED);
130 speed = -1;
131 break;
132 case 5:
133 speed = 1200;
134 break;
135 case 6:
136 logent("HSM No dialtone", _FAILED);
137 speed = -1;
138 break;
139 case 7:
140 logent("HSM detected BUSY", _FAILED);
141 speed = -1;
142 break;
143 case 8:
144 logent("HSM No quiet answer", _FAILED);
145 speed = -1;
146 break;
147 case 10:
148 speed = 2400;
149 break;
150 default:
151 logent("HSM Unknown response", _FAILED);
152 speed = -1;
153 break;
154 }
155
156 } while (speed == 0);
157
158 alarm(0);
159
160 if (speed < 0) {
161 strcpy(devSel, dev->D_line);
162 hyscls24(dh, 0);
163 return CF_DIAL;
164 } else if (speed != dev->D_speed) {
165 DEBUG(4, "changing line speed to %d baud\n", speed);
166 fixline(dh, speed);
167 }
168 }
169 if (dh < 0) {
170 logent(dcname, "CAN'T OPEN");
171 return dh;
172 }
173 DEBUG(4, "hayes ok\n", CNULL);
174 return dh;
175 }
176
hyscls24(fd,flag)177 hyscls24(fd, flag)
178 int fd, flag;
179 {
180 char dcname[20];
181 int fff = 1;
182
183 if (fd > 0) {
184 sprintf(dcname, "/dev/%s", devSel);
185 if (flag)
186 DEBUG(4, "Resetting fd = %d\n", fd);
187 else
188 DEBUG(4, "Hanging up fd = %d\n", fd);
189 /*
190 * Since we have a getty sleeping on this line, when it wakes
191 * up it sends all kinds of garbage to the modem.
192 * Unfortunatly, the modem likes to execute the previous
193 * command when it sees the garbage. The previous command
194 * was to dial the phone, so let's make the last command
195 * reset the modem.
196 */
197 if (!flag)
198 fixline(fd, 2400);
199 write(fd, "\r", 1);
200 sleep(2);
201 write(fd, "+++", 3);
202 sleep(3);
203 write(fd, "\rATH\rATZ\r", 9);
204 sleep(2);
205 ioctl(fd, TIOCFLUSH, &fff);
206
207 if (!flag) {
208 close(fd);
209 delock(devSel);
210 }
211 }
212 }
213