1461ee7cfSbostic /*-
2*5d8c4082Sbostic * Copyright (c) 1985, 1993
3*5d8c4082Sbostic * The Regents of the University of California. All rights reserved.
4461ee7cfSbostic *
5461ee7cfSbostic * %sccs.include.proprietary.c%
6461ee7cfSbostic */
7461ee7cfSbostic
87b2afc14Sralph #ifndef lint
9*5d8c4082Sbostic static char sccsid[] = "@(#)vmacs.c 8.1 (Berkeley) 06/06/93";
10461ee7cfSbostic #endif /* not lint */
117b2afc14Sralph
12d3f4d2b1Sbostic #include "condevs.h"
130d8818b4Srick
147b2afc14Sralph /*
157b2afc14Sralph *
167b2afc14Sralph * A typical 300 baud L-devices entry is
177b2afc14Sralph * ACU /dev/tty10 /dev/tty11,48,1200 300 vmacs
187b2afc14Sralph * where tty10 is the communication line (D_Line),
197b2afc14Sralph * tty11 is the dialer line (D_calldev),
207b2afc14Sralph * the '4' is the dialer address + modem type (viz. dialer 0, Bell 103),
217b2afc14Sralph * and the '8' is the communication port
227b2afc14Sralph * (Note: Based on RVMACS version for 820 dialer. This version
237b2afc14Sralph * developed by Doug Kingston @ BRL, 13 December 83.)
247b2afc14Sralph */
257b2afc14Sralph
267b2afc14Sralph #define SOH 01 /* Abort */
277b2afc14Sralph #define STX 02 /* Access Adaptor */
287b2afc14Sralph #define ETX 03 /* Transfer to Dialer */
297b2afc14Sralph #define SI 017 /* Buffer Empty (end of phone number) */
307b2afc14Sralph
vmacsopn(ph,flds,dev)317b2afc14Sralph vmacsopn(ph, flds, dev)
327b2afc14Sralph char *ph, *flds[];
337b2afc14Sralph struct Devices *dev;
347b2afc14Sralph {
357b2afc14Sralph register int va, i, child;
367b2afc14Sralph register char *p;
377b2afc14Sralph char c, acu[20], com[20];
387b2afc14Sralph char modem, dialer;
397b2afc14Sralph int dialspeed;
407b2afc14Sralph char c_STX = STX;
417b2afc14Sralph char c_ETX = ETX;
427b2afc14Sralph char c_SI = SI;
437b2afc14Sralph char c_SOH = SOH;
447b2afc14Sralph
457b2afc14Sralph /* create child to open comm line */
467b2afc14Sralph child = -1;
477b2afc14Sralph sprintf(com, "/dev/%s", dev->D_line);
487b2afc14Sralph if ((child = fork()) == 0) {
497b2afc14Sralph signal(SIGINT, SIG_DFL);
507b2afc14Sralph open(com, 0);
517b2afc14Sralph DEBUG(5, "%s Opened.", com);
527b2afc14Sralph sleep(5);
537b2afc14Sralph exit(1);
547b2afc14Sralph }
557b2afc14Sralph
567b2afc14Sralph if ((p = index(dev->D_calldev, ',')) == NULL) {
577b2afc14Sralph DEBUG(2, "No dialer/modem specification\n", 0);
587b2afc14Sralph goto failret;
597b2afc14Sralph }
607b2afc14Sralph *p++ = '\0';
617b2afc14Sralph if (*p < '0' || *p > '7') {
627b2afc14Sralph logent(p, "Bad dialer address/modem type");
637b2afc14Sralph goto failret;
647b2afc14Sralph }
657b2afc14Sralph dialer = *p++;
667b2afc14Sralph if (*p < '0' || *p > '>') {
677b2afc14Sralph logent(p, "Bad modem address");
687b2afc14Sralph goto failret;
697b2afc14Sralph }
707b2afc14Sralph modem = *p++;
717b2afc14Sralph if (*p++ == ',')
727b2afc14Sralph dialspeed = atoi (p);
737b2afc14Sralph else
747b2afc14Sralph dialspeed = dev->D_speed;
757b2afc14Sralph if (setjmp(Sjbuf)) {
767b2afc14Sralph logent("vmacsopn", "TIMEOUT");
777b2afc14Sralph i = CF_DIAL;
787b2afc14Sralph goto ret;
797b2afc14Sralph }
807b2afc14Sralph DEBUG(4, "STARTING CALL\n", 0);
817b2afc14Sralph sprintf(acu, "/dev/%s", dev->D_calldev);
827b2afc14Sralph getnextfd();
837b2afc14Sralph signal(SIGALRM, alarmtr);
84f704781bSbloom alarm(60);
857b2afc14Sralph if ((va = open(acu, 2)) < 0) {
867b2afc14Sralph logent(acu, "CAN'T OPEN");
877b2afc14Sralph i = CF_NODEV;
887b2afc14Sralph goto ret;
897b2afc14Sralph }
907b2afc14Sralph DEBUG(5, "ACU %s opened.\n", acu);
91e449bb94Sbloom next_fd = -1;
927b2afc14Sralph fixline(va, dialspeed);
937b2afc14Sralph
947b2afc14Sralph write(va, &c_SOH, 1); /* abort, reset the dialer */
957b2afc14Sralph do {
967b2afc14Sralph if (read (va, &c, 1) != 1) {
977b2afc14Sralph logent ("MACS initialization", _FAILED);
987b2afc14Sralph goto failret;
997b2afc14Sralph }
1007b2afc14Sralph } while ((c&0177) != 'B');
1017b2afc14Sralph DEBUG(5, "ACU initialized\n", 0);
1027b2afc14Sralph
1037b2afc14Sralph write(va, &c_STX, 1); /* start text, access adaptor */
1047b2afc14Sralph write(va, &dialer, 1); /* send dialer address digit */
1057b2afc14Sralph write(va, &modem, 1); /* send modem address digit */
106f704781bSbloom for (p=ph; *p; p++) {
107f704781bSbloom if (*p == '=' || (*p >= '0' && *p <= '9'))
108f704781bSbloom write(va, p, 1);
109f704781bSbloom }
1107b2afc14Sralph write(va, &c_SI, 1); /* send buffer empty */
1117b2afc14Sralph write(va, &c_ETX, 1); /* end of text, initiate call */
1127b2afc14Sralph
1137b2afc14Sralph if (read(va, &c, 1) != 1) {
1147b2afc14Sralph logent("ACU READ", _FAILED);
1157b2afc14Sralph goto failret;
1167b2afc14Sralph }
1177b2afc14Sralph switch(c) {
1187b2afc14Sralph case 'A':
1197b2afc14Sralph /* Fine! */
1207b2afc14Sralph DEBUG(5, "Call connected\n", 0);
1217b2afc14Sralph break;
1227b2afc14Sralph case 'B':
123f704781bSbloom DEBUG(2, "Dialer Timeout or Abort\n", 0);
1247b2afc14Sralph goto failret;
1257b2afc14Sralph case 'D':
1267b2afc14Sralph DEBUG(2, "Dialer format error\n", 0);
1277b2afc14Sralph goto failret;
1287b2afc14Sralph case 'E':
1297b2afc14Sralph DEBUG(2, "Dialer parity error\n", 0);
1307b2afc14Sralph goto failret;
1317b2afc14Sralph case 'F':
1327b2afc14Sralph DEBUG(2, "Phone number too long\n", 0);
1337b2afc14Sralph goto failret;
1347b2afc14Sralph case 'G':
1357b2afc14Sralph DEBUG(2, "Busy signal\n", 0);
1367b2afc14Sralph goto failret;
1377b2afc14Sralph default:
1387b2afc14Sralph DEBUG(2, "Unknown MACS return code '%c'\n", i);
1397b2afc14Sralph goto failret;
1407b2afc14Sralph }
1417b2afc14Sralph /*
1427b2afc14Sralph * open line - will return on carrier
1437b2afc14Sralph */
1447b2afc14Sralph if ((i = open(com, 2)) < 0) {
1457b2afc14Sralph if (errno == EIO)
1467b2afc14Sralph logent("carrier", "LOST");
1477b2afc14Sralph else
1487b2afc14Sralph logent("dialup open", _FAILED);
1497b2afc14Sralph goto failret;
1507b2afc14Sralph }
1517b2afc14Sralph fixline(i, dev->D_speed);
1527b2afc14Sralph goto ret;
1537b2afc14Sralph failret:
1547b2afc14Sralph i = CF_DIAL;
1557b2afc14Sralph ret:
1567b2afc14Sralph alarm(0);
1577b2afc14Sralph if (child > 1)
1587b2afc14Sralph kill(child, SIGKILL);
1597b2afc14Sralph close(va);
160f704781bSbloom sleep(2);
1617b2afc14Sralph return i;
1627b2afc14Sralph }
1637b2afc14Sralph
vmacscls(fd)1647b2afc14Sralph vmacscls(fd)
1657b2afc14Sralph register int fd;
1667b2afc14Sralph {
1677b2afc14Sralph char c_SOH = SOH;
1687b2afc14Sralph
1697b2afc14Sralph DEBUG(2, "MACS close %d\n", fd);
1707b2afc14Sralph write(fd, &c_SOH, 1);
1717b2afc14Sralph /* ioctl(fd, TIOCCDTR, NULL);*/
1727b2afc14Sralph close(fd);
1737b2afc14Sralph }
174