1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 /* 6 * Copyright (c) 1983 Regents of the University of California. 7 * All rights reserved. The Berkeley software License Agreement 8 * specifies the terms and conditions for redistribution. 9 */ 10 #ident "%Z%%M% %I% %E% SMI" /* from UCB 1.5 6/25/83 */ 11 12 /* 13 * Routines for calling up on a Ventel Modem 14 * Define VENNOECHO if the Ventel is strapped for "no echo". 15 */ 16 #include "tip.h" 17 18 #define MAXRETRY 5 19 20 static void sigALRM(); 21 static int timeout = 0; 22 static sigjmp_buf timeoutbuf; 23 24 ven_dialer(num, acu) 25 register char *num; 26 char *acu; 27 { 28 register char *cp; 29 register int connected = 0; 30 struct termios buf; 31 #ifdef ACULOG 32 char line[80]; 33 #endif 34 /* 35 * Get in synch with a couple of carriage returns 36 */ 37 if (!vensync(FD)) { 38 printf("can't synchronize with ventel\n"); 39 #ifdef ACULOG 40 logent(value(HOST), num, "ventel", "can't synch up"); 41 #endif 42 return (0); 43 } 44 if (boolean(value(VERBOSE))) 45 printf("\ndialing..."); 46 fflush(stdout); 47 ioctl(FD, TCGETS, &buf); 48 buf.c_cflag |= HUPCL; 49 ioctl(FD, TCSETSF, &buf); 50 #ifdef VENNOECHO 51 echo("#k$\r$\n$D$I$A$L$:$ "); 52 for (cp = num; *cp; cp++) { 53 sleep(1); 54 write(FD, cp, 1); 55 } 56 echo("\r$\n"); 57 #else 58 echo("k$\r$\n$D$I$A$L$:$ <"); 59 for (cp = num; *cp; cp++) { 60 char c; 61 62 sleep(1); 63 write(FD, cp, 1); 64 read(FD, &c, 1); 65 } 66 echo(">\r$\n"); 67 #endif 68 if (gobble('\n')) 69 connected = gobble('!'); 70 ioctl(FD, TCFLSH, TCIOFLUSH); 71 #ifdef ACULOG 72 if (timeout) { 73 sprintf(line, "%d second dial timeout", 74 number(value(DIALTIMEOUT))); 75 logent(value(HOST), num, "ventel", line); 76 } 77 #endif 78 if (timeout) 79 ven_disconnect(); /* insurance */ 80 return (connected); 81 } 82 83 ven_disconnect() 84 { 85 86 close(FD); 87 } 88 89 ven_abort() 90 { 91 92 write(FD, "\03", 1); 93 close(FD); 94 } 95 96 static int 97 echo(s) 98 register char *s; 99 { 100 char c; 101 102 while (c = *s++) { 103 switch (c) { 104 case '$': 105 read(FD, &c, 1); 106 s++; 107 break; 108 109 case '#': 110 c = *s++; 111 write(FD, &c, 1); 112 break; 113 114 default: 115 write(FD, &c, 1); 116 read(FD, &c, 1); 117 } 118 } 119 } 120 121 static void 122 sigALRM() 123 { 124 125 printf("\07timeout waiting for reply\n"); 126 timeout = 1; 127 siglongjmp(timeoutbuf, 1); 128 } 129 130 static int 131 gobble(match) 132 register char match; 133 { 134 char c; 135 sig_handler_t f; 136 137 f = signal(SIGALRM, (sig_handler_t)sigALRM); 138 timeout = 0; 139 do { 140 if (sigsetjmp(timeoutbuf, 1)) { 141 signal(SIGALRM, f); 142 return (0); 143 } 144 alarm(number(value(DIALTIMEOUT))); 145 read(FD, &c, 1); 146 alarm(0); 147 c &= 0177; 148 #ifdef notdef 149 if (boolean(value(VERBOSE))) 150 putchar(c); 151 #endif 152 } while (c != '\n' && c != match); 153 signal(SIGALRM, SIG_DFL); 154 return (c == match); 155 } 156 157 #define min(a, b) (((a) > (b)) ? (b) : (a)) 158 /* 159 * This convoluted piece of code attempts to get 160 * the ventel in sync. If you don't have FIONREAD 161 * there are gory ways to simulate this. 162 */ 163 static int 164 vensync(fd) 165 { 166 int already = 0, nread; 167 char buf[60]; 168 int dtr = TIOCM_DTR; 169 170 /* 171 * Toggle DTR to force anyone off that might have left 172 * the modem connected, and insure a consistent state 173 * to start from. 174 * 175 * If you don't have the ioctl calls to diddle directly 176 * with DTR, you can always try setting the baud rate to 0. 177 */ 178 ioctl(FD, TIOCMBIC, &dtr); 179 sleep(2); 180 ioctl(FD, TIOCMBIS, &dtr); 181 while (already < MAXRETRY) { 182 /* 183 * After reseting the modem, send it two \r's to 184 * autobaud on. Make sure to delay between them 185 * so the modem can frame the incoming characters. 186 */ 187 write(fd, "\r", 1); 188 #ifdef VMUNIX 189 { 190 #include <sys/time.h> 191 struct timeval tv = {0, 500000}; 192 193 select(0, 0, 0, 0, &tv); 194 } 195 #else 196 sleep(1); 197 #endif 198 write(fd, "\r", 1); 199 sleep(3); 200 if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) { 201 perror("tip: ioctl"); 202 continue; 203 } 204 while (nread > 0) { 205 read(fd, buf, min(nread, 60)); 206 if ((buf[nread - 1] & 0177) == '$') 207 return (1); 208 nread -= min(nread, 60); 209 } 210 sleep(1); 211 already++; 212 } 213 return (0); 214 } 215