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