xref: /original-bsd/usr.bin/uucp/libacu/hys24.c (revision c3e32dec)
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 
24 hyspopn24(telno, flds, dev)
25 char *telno, *flds[];
26 struct Devices *dev;
27 {
28 	return hysopn24(telno, flds, dev, 0);
29 }
30 
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 */
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 
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