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