xref: /original-bsd/usr.bin/uucp/libacu/vmacs.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[] = "@(#)vmacs.c	8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11 
12 #include "condevs.h"
13 
14 /*
15  *
16  * A typical 300 baud L-devices entry is
17  *	ACU /dev/tty10 /dev/tty11,48,1200 300 vmacs
18  * where tty10 is the communication line (D_Line),
19  * tty11 is the dialer line (D_calldev),
20  * the '4' is the dialer address + modem type (viz. dialer 0, Bell 103),
21  * and the '8' is the communication port
22  * (Note: Based on RVMACS version for 820 dialer.  This version
23  *  developed by Doug Kingston @ BRL, 13 December 83.)
24  */
25 
26 #define	SOH	01	/* Abort */
27 #define	STX	02	/* Access Adaptor */
28 #define	ETX	03	/* Transfer to Dialer */
29 #define	SI	017	/* Buffer Empty (end of phone number) */
30 
31 vmacsopn(ph, flds, dev)
32 char *ph, *flds[];
33 struct Devices *dev;
34 {
35 	register int va, i, child;
36 	register char *p;
37 	char c, acu[20], com[20];
38 	char	modem, dialer;
39 	int	dialspeed;
40 	char c_STX = STX;
41 	char c_ETX = ETX;
42 	char c_SI = SI;
43 	char c_SOH = SOH;
44 
45 	/* create child to open comm line */
46 	child = -1;
47 	sprintf(com, "/dev/%s", dev->D_line);
48 	if ((child = fork()) == 0) {
49 		signal(SIGINT, SIG_DFL);
50 		open(com, 0);
51 		DEBUG(5, "%s Opened.", com);
52 		sleep(5);
53 		exit(1);
54 	}
55 
56 	if ((p = index(dev->D_calldev, ',')) == NULL) {
57 		DEBUG(2, "No dialer/modem specification\n", 0);
58 		goto failret;
59 	}
60 	*p++ = '\0';
61 	if (*p < '0' || *p > '7') {
62 		logent(p, "Bad dialer address/modem type");
63 		goto failret;
64 	}
65 	dialer = *p++;
66 	if (*p < '0' || *p > '>') {
67 		logent(p, "Bad modem address");
68 		goto failret;
69 	}
70 	modem = *p++;
71 	if (*p++ == ',')
72 		dialspeed = atoi (p);
73 	else
74 		dialspeed = dev->D_speed;
75 	if (setjmp(Sjbuf)) {
76 		logent("vmacsopn", "TIMEOUT");
77 		i = CF_DIAL;
78 		goto ret;
79 	}
80 	DEBUG(4, "STARTING CALL\n", 0);
81 	sprintf(acu, "/dev/%s", dev->D_calldev);
82 	getnextfd();
83 	signal(SIGALRM, alarmtr);
84 	alarm(60);
85 	if ((va = open(acu, 2)) < 0) {
86 		logent(acu, "CAN'T OPEN");
87 		i = CF_NODEV;
88 		goto ret;
89 	}
90 	DEBUG(5, "ACU %s opened.\n", acu);
91 	next_fd = -1;
92 	fixline(va, dialspeed);
93 
94 	write(va, &c_SOH, 1);		/* abort, reset the dialer */
95 	do {
96 		if (read (va, &c, 1) != 1) {
97 			logent ("MACS initialization", _FAILED);
98 			goto failret;
99 		}
100 	} while ((c&0177) != 'B');
101 	DEBUG(5, "ACU initialized\n", 0);
102 
103 	write(va, &c_STX, 1);		/* start text, access adaptor */
104 	write(va, &dialer, 1);		/* send dialer address digit */
105 	write(va, &modem, 1);		/* send modem address digit */
106 	for (p=ph; *p; p++) {
107 		if (*p == '=' || (*p >= '0' && *p <= '9'))
108 			write(va, p, 1);
109 	}
110 	write(va, &c_SI, 1);		/* send buffer empty */
111 	write(va, &c_ETX, 1);		/* end of text, initiate call */
112 
113 	if (read(va, &c, 1) != 1) {
114 		logent("ACU READ", _FAILED);
115 		goto failret;
116 	}
117 	switch(c) {
118 	case 'A':
119 		/* Fine! */
120 		DEBUG(5, "Call connected\n", 0);
121 		break;
122 	case 'B':
123 		DEBUG(2, "Dialer Timeout or Abort\n", 0);
124 		goto failret;
125 	case 'D':
126 		DEBUG(2, "Dialer format error\n", 0);
127 		goto failret;
128 	case 'E':
129 		DEBUG(2, "Dialer parity error\n", 0);
130 		goto failret;
131 	case 'F':
132 		DEBUG(2, "Phone number too long\n", 0);
133 		goto failret;
134 	case 'G':
135 		DEBUG(2, "Busy signal\n", 0);
136 		goto failret;
137 	default:
138 		DEBUG(2, "Unknown MACS return code '%c'\n", i);
139 		goto failret;
140 	}
141 	/*
142 	 * open line - will return on carrier
143 	 */
144 	if ((i = open(com, 2)) < 0) {
145 		if (errno == EIO)
146 			logent("carrier", "LOST");
147 		else
148 			logent("dialup open", _FAILED);
149 		goto failret;
150 	}
151 	fixline(i, dev->D_speed);
152 	goto ret;
153 failret:
154 	i = CF_DIAL;
155 ret:
156 	alarm(0);
157 	if (child > 1)
158 		kill(child, SIGKILL);
159 	close(va);
160 	sleep(2);
161 	return i;
162 }
163 
164 vmacscls(fd)
165 register int fd;
166 {
167 	char c_SOH = SOH;
168 
169 	DEBUG(2, "MACS close %d\n", fd);
170 	write(fd, &c_SOH, 1);
171 /*	ioctl(fd, TIOCCDTR, NULL);*/
172 	close(fd);
173 }
174