1 #ifndef lint 2 static char sccsid[] = "@(#)vmacs.c 4.5 (Berkeley) 02/24/88"; 3 #endif 4 5 #include "../condevs.h" 6 7 /* 8 * 9 * A typical 300 baud L-devices entry is 10 * ACU /dev/tty10 /dev/tty11,48,1200 300 vmacs 11 * where tty10 is the communication line (D_Line), 12 * tty11 is the dialer line (D_calldev), 13 * the '4' is the dialer address + modem type (viz. dialer 0, Bell 103), 14 * and the '8' is the communication port 15 * (Note: Based on RVMACS version for 820 dialer. This version 16 * developed by Doug Kingston @ BRL, 13 December 83.) 17 */ 18 19 #define SOH 01 /* Abort */ 20 #define STX 02 /* Access Adaptor */ 21 #define ETX 03 /* Transfer to Dialer */ 22 #define SI 017 /* Buffer Empty (end of phone number) */ 23 24 vmacsopn(ph, flds, dev) 25 char *ph, *flds[]; 26 struct Devices *dev; 27 { 28 register int va, i, child; 29 register char *p; 30 char c, acu[20], com[20]; 31 char modem, dialer; 32 int dialspeed; 33 char c_STX = STX; 34 char c_ETX = ETX; 35 char c_SI = SI; 36 char c_SOH = SOH; 37 38 /* create child to open comm line */ 39 child = -1; 40 sprintf(com, "/dev/%s", dev->D_line); 41 if ((child = fork()) == 0) { 42 signal(SIGINT, SIG_DFL); 43 open(com, 0); 44 DEBUG(5, "%s Opened.", com); 45 sleep(5); 46 exit(1); 47 } 48 49 if ((p = index(dev->D_calldev, ',')) == NULL) { 50 DEBUG(2, "No dialer/modem specification\n", 0); 51 goto failret; 52 } 53 *p++ = '\0'; 54 if (*p < '0' || *p > '7') { 55 logent(p, "Bad dialer address/modem type"); 56 goto failret; 57 } 58 dialer = *p++; 59 if (*p < '0' || *p > '>') { 60 logent(p, "Bad modem address"); 61 goto failret; 62 } 63 modem = *p++; 64 if (*p++ == ',') 65 dialspeed = atoi (p); 66 else 67 dialspeed = dev->D_speed; 68 if (setjmp(Sjbuf)) { 69 logent("vmacsopn", "TIMEOUT"); 70 i = CF_DIAL; 71 goto ret; 72 } 73 DEBUG(4, "STARTING CALL\n", 0); 74 sprintf(acu, "/dev/%s", dev->D_calldev); 75 getnextfd(); 76 signal(SIGALRM, alarmtr); 77 alarm(60); 78 if ((va = open(acu, 2)) < 0) { 79 logent(acu, "CAN'T OPEN"); 80 i = CF_NODEV; 81 goto ret; 82 } 83 DEBUG(5, "ACU %s opened.\n", acu); 84 next_fd = -1; 85 fixline(va, dialspeed); 86 87 write(va, &c_SOH, 1); /* abort, reset the dialer */ 88 do { 89 if (read (va, &c, 1) != 1) { 90 logent ("MACS initialization", _FAILED); 91 goto failret; 92 } 93 } while ((c&0177) != 'B'); 94 DEBUG(5, "ACU initialized\n", 0); 95 96 write(va, &c_STX, 1); /* start text, access adaptor */ 97 write(va, &dialer, 1); /* send dialer address digit */ 98 write(va, &modem, 1); /* send modem address digit */ 99 for (p=ph; *p; p++) { 100 if (*p == '=' || (*p >= '0' && *p <= '9')) 101 write(va, p, 1); 102 } 103 write(va, &c_SI, 1); /* send buffer empty */ 104 write(va, &c_ETX, 1); /* end of text, initiate call */ 105 106 if (read(va, &c, 1) != 1) { 107 logent("ACU READ", _FAILED); 108 goto failret; 109 } 110 switch(c) { 111 case 'A': 112 /* Fine! */ 113 DEBUG(5, "Call connected\n", 0); 114 break; 115 case 'B': 116 DEBUG(2, "Dialer Timeout or Abort\n", 0); 117 goto failret; 118 case 'D': 119 DEBUG(2, "Dialer format error\n", 0); 120 goto failret; 121 case 'E': 122 DEBUG(2, "Dialer parity error\n", 0); 123 goto failret; 124 case 'F': 125 DEBUG(2, "Phone number too long\n", 0); 126 goto failret; 127 case 'G': 128 DEBUG(2, "Busy signal\n", 0); 129 goto failret; 130 default: 131 DEBUG(2, "Unknown MACS return code '%c'\n", i); 132 goto failret; 133 } 134 /* 135 * open line - will return on carrier 136 */ 137 if ((i = open(com, 2)) < 0) { 138 if (errno == EIO) 139 logent("carrier", "LOST"); 140 else 141 logent("dialup open", _FAILED); 142 goto failret; 143 } 144 fixline(i, dev->D_speed); 145 goto ret; 146 failret: 147 i = CF_DIAL; 148 ret: 149 alarm(0); 150 if (child > 1) 151 kill(child, SIGKILL); 152 close(va); 153 sleep(2); 154 return i; 155 } 156 157 vmacscls(fd) 158 register int fd; 159 { 160 char c_SOH = SOH; 161 162 DEBUG(2, "MACS close %d\n", fd); 163 write(fd, &c_SOH, 1); 164 /* ioctl(fd, TIOCCDTR, NULL);*/ 165 close(fd); 166 } 167