1 /*- 2 * Copyright (c) 1985, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.proprietary.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)rvmacs.c 8.1 (Berkeley) 06/06/93"; 10 #endif /* not lint */ 11 12 #include "condevs.h" 13 14 /* 15 * Racal-Vadic 'RV820' MACS system with 831 adaptor. 16 * A typical 300 baud L-devices entry is 17 * ACU tty10 tty11,48 300 rvmacs 18 * where tty10 is the communication line (D_Line), 19 * tty11 is the dialer line (D_calldev), 20 * the '4' is the dialer address + modem type (viz. dialer 0, Bell 103), 21 * the '8' is the communication port, 22 * We assume the dialer speed is 1200 baud unless MULTISPEED is defined. 23 * We extended the semantics of the L-devices entry to allow you 24 * to set the speed at which the computer talks to the dialer: 25 * ACU cul0 cua0,0<,2400 1200 rvmacs 26 * This is interpreted as above, except that the number following the second 27 * comma in the third field is taken to be the speed at which the computer 28 * must communicate with the dialer. (If omitted, it defaults to the value 29 * in the fourth field.) Note -- just after the call completes and you get 30 * carrier, the line speed is reset to the speed indicated in the fourth field. 31 * To get this ability, define "MULTISPEED", as below. 32 * 33 */ 34 #define MULTISPEED /* for dialers which work at various speeds */ 35 36 #define STX 02 /* Access Adaptor */ 37 #define ETX 03 /* Transfer to Dialer */ 38 #define SI 017 /* Buffer Empty (end of phone number) */ 39 #define ABORT 01 /* Abort */ 40 41 #define pc(fd, x) (c = x, write(fd, &c, 1)) 42 43 rvmacsopn(ph, flds, dev) 44 char *ph, *flds[]; 45 struct Devices *dev; 46 { 47 register int va, i, child; 48 register char *p; 49 char c, acu[20], com[20]; 50 int baudrate; 51 int timelim; 52 int pid, status; 53 int zero = 0; 54 #ifdef MULTISPEED 55 char *pp; 56 #else !MULTISPEED 57 struct sgttyb sg; 58 #endif MULTISPEED 59 60 child = -1; 61 sprintf(com, "/dev/%s", dev->D_line); 62 sprintf(acu, "/dev/%s", dev->D_calldev); 63 if ((p = index(acu, ',')) == NULL) { 64 DEBUG(2, "No dialer/modem specification\n", 0); 65 return CF_DIAL; 66 } 67 *p++ = '\0'; 68 #ifdef MULTISPEED 69 baudrate = dev->D_speed; 70 if ((pp = index(p, ',')) != NULL){ 71 baudrate = atoi(pp+1); 72 DEBUG(5, "Using speed %d baud\n", baudrate); 73 } 74 #endif MULTISPEED 75 if (setjmp(Sjbuf)) { 76 logent("rvmacsopn", "TIMEOUT"); 77 goto failret; 78 } 79 DEBUG(4, "STARTING CALL\n", 0); 80 getnextfd(); 81 signal(SIGALRM, alarmtr); 82 timelim = 5 * strlen(ph); 83 alarm(timelim < 45 ? 45 : timelim); 84 85 if ((va = open(acu, 2)) < 0) { 86 logent(acu, "CAN'T OPEN"); 87 alarm(0); 88 return CF_DIAL; 89 } 90 91 /* rti!trt: avoid passing acu file descriptor to children */ 92 next_fd = -1; 93 fioclex(va); 94 95 if ((child = fork()) == 0) { 96 /* create child to do dialing */ 97 sleep(2); 98 fclose(stdin); 99 fclose(stdout); 100 #ifdef MULTISPEED 101 fixline(va, baudrate); 102 #else !MULTISPEED 103 sg.sg_flags = RAW|ANYP; 104 sg.sg_ispeed = sg.sg_ospeed = B1200; 105 ioctl(va, TIOCSETP, &sg); 106 #endif MULTISPEED 107 pc(va, ABORT); 108 sleep(1); 109 ioctl(va, TIOCFLUSH, &zero); 110 pc(va, STX); /* access adaptor */ 111 pc(va, *p++); /* Send Dialer Address Digit */ 112 pc(va, *p); /* Send Modem Address Digit */ 113 while (*ph && *ph != '<') { 114 switch (*ph) { 115 case '_': 116 case '-': 117 case '=': 118 pc(va, '='); 119 break; 120 default: 121 if (*ph >= '0' && *ph <= '9') 122 pc(va, *ph); 123 break; 124 } 125 ph++; 126 } 127 pc(va, '<'); /* Transfer Control to Modem (sigh) */ 128 pc(va, SI); /* Send Buffer Empty */ 129 pc(va, ETX); /* Initiate Call */ 130 sleep(1); 131 132 if (read(va, &c, 1) != 1) { 133 close(va); 134 logent("ACU READ", _FAILED); 135 exit(1); 136 } 137 if (c == 'B' || c == 'G') { 138 char cc; 139 pc(va, ABORT); 140 read(va, &cc, 1); 141 } 142 DEBUG(4, "Dialer returned %c\n", c); 143 close(va); 144 exit(c != 'A'); 145 } 146 /* 147 * open line - will return on carrier 148 */ 149 if ((i = open(com, 2)) < 0) { 150 if (errno == EIO) 151 logent("carrier", "LOST"); 152 else 153 logent("dialup open", _FAILED); 154 goto failret; 155 } 156 while ((pid = wait(&status)) != child && pid != -1) 157 ; 158 alarm(0); 159 if (status) { 160 close(i); 161 close(va); /* XXX */ 162 return CF_DIAL; 163 } 164 fixline(i, dev->D_speed); 165 return i; 166 167 failret: 168 alarm(0); 169 close(va); 170 if (child != -1) 171 kill(child, SIGKILL); 172 return CF_DIAL; 173 } 174 175 rvmacscls(fd) 176 register int fd; 177 { 178 if (fd > 0) { 179 char c; 180 181 pc(fd, ABORT); 182 ioctl(fd, TIOCCDTR, STBNULL); 183 sleep(1); 184 ioctl(fd, TIOCNXCL, STBNULL); 185 close(fd); 186 delock(devSel); 187 } 188 } 189