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[] = "@(#)rvmacs.c 8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11
12 #include "condevs.h"
13
14 /*
15 * Racal-Vadic 'RV820' MACS system with 831 adaptor.
16 * A typical 300 baud L-devices entry is
17 * ACU tty10 tty11,48 300 rvmacs
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 * the '8' is the communication port,
22 * We assume the dialer speed is 1200 baud unless MULTISPEED is defined.
23 * We extended the semantics of the L-devices entry to allow you
24 * to set the speed at which the computer talks to the dialer:
25 * ACU cul0 cua0,0<,2400 1200 rvmacs
26 * This is interpreted as above, except that the number following the second
27 * comma in the third field is taken to be the speed at which the computer
28 * must communicate with the dialer. (If omitted, it defaults to the value
29 * in the fourth field.) Note -- just after the call completes and you get
30 * carrier, the line speed is reset to the speed indicated in the fourth field.
31 * To get this ability, define "MULTISPEED", as below.
32 *
33 */
34 #define MULTISPEED /* for dialers which work at various speeds */
35
36 #define STX 02 /* Access Adaptor */
37 #define ETX 03 /* Transfer to Dialer */
38 #define SI 017 /* Buffer Empty (end of phone number) */
39 #define ABORT 01 /* Abort */
40
41 #define pc(fd, x) (c = x, write(fd, &c, 1))
42
rvmacsopn(ph,flds,dev)43 rvmacsopn(ph, flds, dev)
44 char *ph, *flds[];
45 struct Devices *dev;
46 {
47 register int va, i, child;
48 register char *p;
49 char c, acu[20], com[20];
50 int baudrate;
51 int timelim;
52 int pid, status;
53 int zero = 0;
54 #ifdef MULTISPEED
55 char *pp;
56 #else !MULTISPEED
57 struct sgttyb sg;
58 #endif MULTISPEED
59
60 child = -1;
61 sprintf(com, "/dev/%s", dev->D_line);
62 sprintf(acu, "/dev/%s", dev->D_calldev);
63 if ((p = index(acu, ',')) == NULL) {
64 DEBUG(2, "No dialer/modem specification\n", 0);
65 return CF_DIAL;
66 }
67 *p++ = '\0';
68 #ifdef MULTISPEED
69 baudrate = dev->D_speed;
70 if ((pp = index(p, ',')) != NULL){
71 baudrate = atoi(pp+1);
72 DEBUG(5, "Using speed %d baud\n", baudrate);
73 }
74 #endif MULTISPEED
75 if (setjmp(Sjbuf)) {
76 logent("rvmacsopn", "TIMEOUT");
77 goto failret;
78 }
79 DEBUG(4, "STARTING CALL\n", 0);
80 getnextfd();
81 signal(SIGALRM, alarmtr);
82 timelim = 5 * strlen(ph);
83 alarm(timelim < 45 ? 45 : timelim);
84
85 if ((va = open(acu, 2)) < 0) {
86 logent(acu, "CAN'T OPEN");
87 alarm(0);
88 return CF_DIAL;
89 }
90
91 /* rti!trt: avoid passing acu file descriptor to children */
92 next_fd = -1;
93 fioclex(va);
94
95 if ((child = fork()) == 0) {
96 /* create child to do dialing */
97 sleep(2);
98 fclose(stdin);
99 fclose(stdout);
100 #ifdef MULTISPEED
101 fixline(va, baudrate);
102 #else !MULTISPEED
103 sg.sg_flags = RAW|ANYP;
104 sg.sg_ispeed = sg.sg_ospeed = B1200;
105 ioctl(va, TIOCSETP, &sg);
106 #endif MULTISPEED
107 pc(va, ABORT);
108 sleep(1);
109 ioctl(va, TIOCFLUSH, &zero);
110 pc(va, STX); /* access adaptor */
111 pc(va, *p++); /* Send Dialer Address Digit */
112 pc(va, *p); /* Send Modem Address Digit */
113 while (*ph && *ph != '<') {
114 switch (*ph) {
115 case '_':
116 case '-':
117 case '=':
118 pc(va, '=');
119 break;
120 default:
121 if (*ph >= '0' && *ph <= '9')
122 pc(va, *ph);
123 break;
124 }
125 ph++;
126 }
127 pc(va, '<'); /* Transfer Control to Modem (sigh) */
128 pc(va, SI); /* Send Buffer Empty */
129 pc(va, ETX); /* Initiate Call */
130 sleep(1);
131
132 if (read(va, &c, 1) != 1) {
133 close(va);
134 logent("ACU READ", _FAILED);
135 exit(1);
136 }
137 if (c == 'B' || c == 'G') {
138 char cc;
139 pc(va, ABORT);
140 read(va, &cc, 1);
141 }
142 DEBUG(4, "Dialer returned %c\n", c);
143 close(va);
144 exit(c != 'A');
145 }
146 /*
147 * open line - will return on carrier
148 */
149 if ((i = open(com, 2)) < 0) {
150 if (errno == EIO)
151 logent("carrier", "LOST");
152 else
153 logent("dialup open", _FAILED);
154 goto failret;
155 }
156 while ((pid = wait(&status)) != child && pid != -1)
157 ;
158 alarm(0);
159 if (status) {
160 close(i);
161 close(va); /* XXX */
162 return CF_DIAL;
163 }
164 fixline(i, dev->D_speed);
165 return i;
166
167 failret:
168 alarm(0);
169 close(va);
170 if (child != -1)
171 kill(child, SIGKILL);
172 return CF_DIAL;
173 }
174
rvmacscls(fd)175 rvmacscls(fd)
176 register int fd;
177 {
178 if (fd > 0) {
179 char c;
180
181 pc(fd, ABORT);
182 ioctl(fd, TIOCCDTR, STBNULL);
183 sleep(1);
184 ioctl(fd, TIOCNXCL, STBNULL);
185 close(fd);
186 delock(devSel);
187 }
188 }
189