1*48651Sbostic /*- 2*48651Sbostic * Copyright (c) 1985 The Regents of the University of California. 3*48651Sbostic * All rights reserved. 4*48651Sbostic * 5*48651Sbostic * %sccs.include.proprietary.c% 6*48651Sbostic */ 7*48651Sbostic 817787Sralph #ifndef lint 9*48651Sbostic static char sccsid[] = "@(#)vmacs.c 4.7 (Berkeley) 04/24/91"; 10*48651Sbostic #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 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 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