148651Sbostic /*-
2*62384Sbostic * Copyright (c) 1985, 1993
3*62384Sbostic * The Regents of the University of California. All rights reserved.
448651Sbostic *
548651Sbostic * %sccs.include.proprietary.c%
648651Sbostic */
748651Sbostic
817787Sralph #ifndef lint
9*62384Sbostic static char sccsid[] = "@(#)vmacs.c 8.1 (Berkeley) 06/06/93";
1048651Sbostic #endif /* not lint */
1117787Sralph
1246875Sbostic #include "condevs.h"
1333590Srick
1417787Sralph /*
1517787Sralph *
1617787Sralph * A typical 300 baud L-devices entry is
1717787Sralph * ACU /dev/tty10 /dev/tty11,48,1200 300 vmacs
1817787Sralph * where tty10 is the communication line (D_Line),
1917787Sralph * tty11 is the dialer line (D_calldev),
2017787Sralph * the '4' is the dialer address + modem type (viz. dialer 0, Bell 103),
2117787Sralph * and the '8' is the communication port
2217787Sralph * (Note: Based on RVMACS version for 820 dialer. This version
2317787Sralph * developed by Doug Kingston @ BRL, 13 December 83.)
2417787Sralph */
2517787Sralph
2617787Sralph #define SOH 01 /* Abort */
2717787Sralph #define STX 02 /* Access Adaptor */
2817787Sralph #define ETX 03 /* Transfer to Dialer */
2917787Sralph #define SI 017 /* Buffer Empty (end of phone number) */
3017787Sralph
vmacsopn(ph,flds,dev)3117787Sralph vmacsopn(ph, flds, dev)
3217787Sralph char *ph, *flds[];
3317787Sralph struct Devices *dev;
3417787Sralph {
3517787Sralph register int va, i, child;
3617787Sralph register char *p;
3717787Sralph char c, acu[20], com[20];
3817787Sralph char modem, dialer;
3917787Sralph int dialspeed;
4017787Sralph char c_STX = STX;
4117787Sralph char c_ETX = ETX;
4217787Sralph char c_SI = SI;
4317787Sralph char c_SOH = SOH;
4417787Sralph
4517787Sralph /* create child to open comm line */
4617787Sralph child = -1;
4717787Sralph sprintf(com, "/dev/%s", dev->D_line);
4817787Sralph if ((child = fork()) == 0) {
4917787Sralph signal(SIGINT, SIG_DFL);
5017787Sralph open(com, 0);
5117787Sralph DEBUG(5, "%s Opened.", com);
5217787Sralph sleep(5);
5317787Sralph exit(1);
5417787Sralph }
5517787Sralph
5617787Sralph if ((p = index(dev->D_calldev, ',')) == NULL) {
5717787Sralph DEBUG(2, "No dialer/modem specification\n", 0);
5817787Sralph goto failret;
5917787Sralph }
6017787Sralph *p++ = '\0';
6117787Sralph if (*p < '0' || *p > '7') {
6217787Sralph logent(p, "Bad dialer address/modem type");
6317787Sralph goto failret;
6417787Sralph }
6517787Sralph dialer = *p++;
6617787Sralph if (*p < '0' || *p > '>') {
6717787Sralph logent(p, "Bad modem address");
6817787Sralph goto failret;
6917787Sralph }
7017787Sralph modem = *p++;
7117787Sralph if (*p++ == ',')
7217787Sralph dialspeed = atoi (p);
7317787Sralph else
7417787Sralph dialspeed = dev->D_speed;
7517787Sralph if (setjmp(Sjbuf)) {
7617787Sralph logent("vmacsopn", "TIMEOUT");
7717787Sralph i = CF_DIAL;
7817787Sralph goto ret;
7917787Sralph }
8017787Sralph DEBUG(4, "STARTING CALL\n", 0);
8117787Sralph sprintf(acu, "/dev/%s", dev->D_calldev);
8217787Sralph getnextfd();
8317787Sralph signal(SIGALRM, alarmtr);
8423705Sbloom alarm(60);
8517787Sralph if ((va = open(acu, 2)) < 0) {
8617787Sralph logent(acu, "CAN'T OPEN");
8717787Sralph i = CF_NODEV;
8817787Sralph goto ret;
8917787Sralph }
9017787Sralph DEBUG(5, "ACU %s opened.\n", acu);
9125157Sbloom next_fd = -1;
9217787Sralph fixline(va, dialspeed);
9317787Sralph
9417787Sralph write(va, &c_SOH, 1); /* abort, reset the dialer */
9517787Sralph do {
9617787Sralph if (read (va, &c, 1) != 1) {
9717787Sralph logent ("MACS initialization", _FAILED);
9817787Sralph goto failret;
9917787Sralph }
10017787Sralph } while ((c&0177) != 'B');
10117787Sralph DEBUG(5, "ACU initialized\n", 0);
10217787Sralph
10317787Sralph write(va, &c_STX, 1); /* start text, access adaptor */
10417787Sralph write(va, &dialer, 1); /* send dialer address digit */
10517787Sralph write(va, &modem, 1); /* send modem address digit */
10623705Sbloom for (p=ph; *p; p++) {
10723705Sbloom if (*p == '=' || (*p >= '0' && *p <= '9'))
10823705Sbloom write(va, p, 1);
10923705Sbloom }
11017787Sralph write(va, &c_SI, 1); /* send buffer empty */
11117787Sralph write(va, &c_ETX, 1); /* end of text, initiate call */
11217787Sralph
11317787Sralph if (read(va, &c, 1) != 1) {
11417787Sralph logent("ACU READ", _FAILED);
11517787Sralph goto failret;
11617787Sralph }
11717787Sralph switch(c) {
11817787Sralph case 'A':
11917787Sralph /* Fine! */
12017787Sralph DEBUG(5, "Call connected\n", 0);
12117787Sralph break;
12217787Sralph case 'B':
12323705Sbloom DEBUG(2, "Dialer Timeout or Abort\n", 0);
12417787Sralph goto failret;
12517787Sralph case 'D':
12617787Sralph DEBUG(2, "Dialer format error\n", 0);
12717787Sralph goto failret;
12817787Sralph case 'E':
12917787Sralph DEBUG(2, "Dialer parity error\n", 0);
13017787Sralph goto failret;
13117787Sralph case 'F':
13217787Sralph DEBUG(2, "Phone number too long\n", 0);
13317787Sralph goto failret;
13417787Sralph case 'G':
13517787Sralph DEBUG(2, "Busy signal\n", 0);
13617787Sralph goto failret;
13717787Sralph default:
13817787Sralph DEBUG(2, "Unknown MACS return code '%c'\n", i);
13917787Sralph goto failret;
14017787Sralph }
14117787Sralph /*
14217787Sralph * open line - will return on carrier
14317787Sralph */
14417787Sralph if ((i = open(com, 2)) < 0) {
14517787Sralph if (errno == EIO)
14617787Sralph logent("carrier", "LOST");
14717787Sralph else
14817787Sralph logent("dialup open", _FAILED);
14917787Sralph goto failret;
15017787Sralph }
15117787Sralph fixline(i, dev->D_speed);
15217787Sralph goto ret;
15317787Sralph failret:
15417787Sralph i = CF_DIAL;
15517787Sralph ret:
15617787Sralph alarm(0);
15717787Sralph if (child > 1)
15817787Sralph kill(child, SIGKILL);
15917787Sralph close(va);
16023705Sbloom sleep(2);
16117787Sralph return i;
16217787Sralph }
16317787Sralph
vmacscls(fd)16417787Sralph vmacscls(fd)
16517787Sralph register int fd;
16617787Sralph {
16717787Sralph char c_SOH = SOH;
16817787Sralph
16917787Sralph DEBUG(2, "MACS close %d\n", fd);
17017787Sralph write(fd, &c_SOH, 1);
17117787Sralph /* ioctl(fd, TIOCCDTR, NULL);*/
17217787Sralph close(fd);
17317787Sralph }
174