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
817779Sralph #ifndef lint
9*62384Sbostic static char sccsid[] = "@(#)rvmacs.c 8.1 (Berkeley) 06/06/93";
1048651Sbostic #endif /* not lint */
1117779Sralph
1246875Sbostic #include "condevs.h"
1317779Sralph
1417779Sralph /*
1517779Sralph * Racal-Vadic 'RV820' MACS system with 831 adaptor.
1617779Sralph * A typical 300 baud L-devices entry is
1717779Sralph * ACU tty10 tty11,48 300 rvmacs
1817779Sralph * where tty10 is the communication line (D_Line),
1917779Sralph * tty11 is the dialer line (D_calldev),
2017779Sralph * the '4' is the dialer address + modem type (viz. dialer 0, Bell 103),
2117779Sralph * the '8' is the communication port,
2225161Sbloom * We assume the dialer speed is 1200 baud unless MULTISPEED is defined.
2325161Sbloom * We extended the semantics of the L-devices entry to allow you
2425161Sbloom * to set the speed at which the computer talks to the dialer:
2525161Sbloom * ACU cul0 cua0,0<,2400 1200 rvmacs
2625161Sbloom * This is interpreted as above, except that the number following the second
2725161Sbloom * comma in the third field is taken to be the speed at which the computer
2825161Sbloom * must communicate with the dialer. (If omitted, it defaults to the value
2925161Sbloom * in the fourth field.) Note -- just after the call completes and you get
3025161Sbloom * carrier, the line speed is reset to the speed indicated in the fourth field.
3125161Sbloom * To get this ability, define "MULTISPEED", as below.
3225161Sbloom *
3317779Sralph */
3425161Sbloom #define MULTISPEED /* for dialers which work at various speeds */
3517779Sralph
3617779Sralph #define STX 02 /* Access Adaptor */
3717779Sralph #define ETX 03 /* Transfer to Dialer */
3817779Sralph #define SI 017 /* Buffer Empty (end of phone number) */
3917779Sralph #define ABORT 01 /* Abort */
4017779Sralph
4117779Sralph #define pc(fd, x) (c = x, write(fd, &c, 1))
4217779Sralph
rvmacsopn(ph,flds,dev)4317779Sralph rvmacsopn(ph, flds, dev)
4417779Sralph char *ph, *flds[];
4517779Sralph struct Devices *dev;
4617779Sralph {
4717779Sralph register int va, i, child;
4817779Sralph register char *p;
4917779Sralph char c, acu[20], com[20];
5017779Sralph int baudrate;
5117779Sralph int timelim;
5217779Sralph int pid, status;
5317779Sralph int zero = 0;
5425254Sbloom #ifdef MULTISPEED
5525254Sbloom char *pp;
5625254Sbloom #else !MULTISPEED
5717779Sralph struct sgttyb sg;
5825254Sbloom #endif MULTISPEED
5917779Sralph
6017779Sralph child = -1;
6117779Sralph sprintf(com, "/dev/%s", dev->D_line);
6217779Sralph sprintf(acu, "/dev/%s", dev->D_calldev);
6317779Sralph if ((p = index(acu, ',')) == NULL) {
6417779Sralph DEBUG(2, "No dialer/modem specification\n", 0);
6517779Sralph return CF_DIAL;
6617779Sralph }
6717779Sralph *p++ = '\0';
6825161Sbloom #ifdef MULTISPEED
6925161Sbloom baudrate = dev->D_speed;
7025161Sbloom if ((pp = index(p, ',')) != NULL){
7125161Sbloom baudrate = atoi(pp+1);
7225161Sbloom DEBUG(5, "Using speed %d baud\n", baudrate);
7325161Sbloom }
7425161Sbloom #endif MULTISPEED
7517779Sralph if (setjmp(Sjbuf)) {
7617779Sralph logent("rvmacsopn", "TIMEOUT");
7717779Sralph goto failret;
7817779Sralph }
7917779Sralph DEBUG(4, "STARTING CALL\n", 0);
8017779Sralph getnextfd();
8117779Sralph signal(SIGALRM, alarmtr);
8217779Sralph timelim = 5 * strlen(ph);
8317779Sralph alarm(timelim < 45 ? 45 : timelim);
8417779Sralph
8517779Sralph if ((va = open(acu, 2)) < 0) {
8617779Sralph logent(acu, "CAN'T OPEN");
8717779Sralph alarm(0);
8817779Sralph return CF_DIAL;
8917779Sralph }
9017779Sralph
9117779Sralph /* rti!trt: avoid passing acu file descriptor to children */
9217779Sralph next_fd = -1;
9317779Sralph fioclex(va);
9417779Sralph
9517779Sralph if ((child = fork()) == 0) {
9617779Sralph /* create child to do dialing */
9717779Sralph sleep(2);
9817779Sralph fclose(stdin);
9917779Sralph fclose(stdout);
10025161Sbloom #ifdef MULTISPEED
10125161Sbloom fixline(va, baudrate);
10225161Sbloom #else !MULTISPEED
10317779Sralph sg.sg_flags = RAW|ANYP;
10417779Sralph sg.sg_ispeed = sg.sg_ospeed = B1200;
10517779Sralph ioctl(va, TIOCSETP, &sg);
10625161Sbloom #endif MULTISPEED
10717779Sralph pc(va, ABORT);
10817779Sralph sleep(1);
10917779Sralph ioctl(va, TIOCFLUSH, &zero);
11017779Sralph pc(va, STX); /* access adaptor */
11117779Sralph pc(va, *p++); /* Send Dialer Address Digit */
11217779Sralph pc(va, *p); /* Send Modem Address Digit */
11317779Sralph while (*ph && *ph != '<') {
11417779Sralph switch (*ph) {
11517779Sralph case '_':
11617779Sralph case '-':
11717779Sralph case '=':
11817779Sralph pc(va, '=');
11917779Sralph break;
12017779Sralph default:
12117779Sralph if (*ph >= '0' && *ph <= '9')
12217779Sralph pc(va, *ph);
12317779Sralph break;
12417779Sralph }
12517779Sralph ph++;
12617779Sralph }
12717779Sralph pc(va, '<'); /* Transfer Control to Modem (sigh) */
12817779Sralph pc(va, SI); /* Send Buffer Empty */
12917779Sralph pc(va, ETX); /* Initiate Call */
13017779Sralph sleep(1);
13117779Sralph
13217779Sralph if (read(va, &c, 1) != 1) {
13317779Sralph close(va);
13417779Sralph logent("ACU READ", _FAILED);
13517779Sralph exit(1);
13617779Sralph }
13717779Sralph if (c == 'B' || c == 'G') {
13817779Sralph char cc;
13917779Sralph pc(va, ABORT);
14017779Sralph read(va, &cc, 1);
14117779Sralph }
14217779Sralph DEBUG(4, "Dialer returned %c\n", c);
14317779Sralph close(va);
14417779Sralph exit(c != 'A');
14517779Sralph }
14617779Sralph /*
14717779Sralph * open line - will return on carrier
14817779Sralph */
14917779Sralph if ((i = open(com, 2)) < 0) {
15017779Sralph if (errno == EIO)
15117779Sralph logent("carrier", "LOST");
15217779Sralph else
15317779Sralph logent("dialup open", _FAILED);
15417779Sralph goto failret;
15517779Sralph }
15617779Sralph while ((pid = wait(&status)) != child && pid != -1)
15717779Sralph ;
15817779Sralph alarm(0);
15917779Sralph if (status) {
16017779Sralph close(i);
16117779Sralph close(va); /* XXX */
16217779Sralph return CF_DIAL;
16317779Sralph }
16417779Sralph fixline(i, dev->D_speed);
16517779Sralph return i;
16617779Sralph
16717779Sralph failret:
16817779Sralph alarm(0);
16917779Sralph close(va);
17017779Sralph if (child != -1)
17117779Sralph kill(child, SIGKILL);
17217779Sralph return CF_DIAL;
17317779Sralph }
17417779Sralph
rvmacscls(fd)17517779Sralph rvmacscls(fd)
17617779Sralph register int fd;
17717779Sralph {
17817779Sralph if (fd > 0) {
17929405Sbloom char c;
18029405Sbloom
18129405Sbloom pc(fd, ABORT);
18217779Sralph ioctl(fd, TIOCCDTR, STBNULL);
18317779Sralph sleep(1);
18417779Sralph ioctl(fd, TIOCNXCL, STBNULL);
18517779Sralph close(fd);
18617779Sralph delock(devSel);
18717779Sralph }
18817779Sralph }
189