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